HashMap 和 Hashtable 的区别

一、继承的父类不同

  • HashMap继承自AbstractMap类,而Hashtable继承自Dictionary类。尽管它们实现的接口都是Map接口,但由于继承的父类不同,导致它们在一些行为和方法上存在差异。

二、线程安全性不同

  • HashMap是非同步的,这意味着它不是线程安全的。在多个线程同时访问HashMap时,如果没有适当的同步机制,可能会导致数据不一致的问题。
  • Hashtable是线程安全的,它的方法被synchronized修饰,因此在多线程环境下可以直接使用Hashtable而无需额外的同步处理。但需要注意的是,尽管Hashtable是线程安全的,但将Hashtable与多线程访问结合使用并不总是安全的,因为只有当方法是同步的时才能保证线程安全。

三、对null值的支持不同

  • HashMap允许使用null作为键(key),但建议尽量避免这样做,因为当使用null作为键时,该键总是存储在table数组的第一个节点上,这可能会影响HashMap的性能。HashMap也允许一个或多个键所对应的值为null。
  • Hashtable则不允许使用null作为键或值。如果尝试在Hashtable中插入null键或值,将在运行时抛出NullPointerException异常。

四、遍历方式的不同

  • HashMap只支持Iterator遍历方式。
  • Hashtable除了支持Iterator遍历方式外,还支持Enumeration遍历方式。这是由于Hashtable的历史原因造成的,它在Java早期版本中就已经存在,而那时还没有引入Iterator接口。

五、哈希计算方法与扩容机制不同

  • HashMap在计算哈希值时,对key的hashCode进行了二次哈希,以获得更好的散列值,然后对table数组长度取模。当已用容量超过总容量乘以负载因子时,HashMap会进行扩容,扩容规则为当前容量翻倍(但不超过Integer.MAX_VALUE - 8)。
  • Hashtable在计算哈希值时,直接使用key的hashCode对table数组的长度进行取模。当已用容量超过总容量乘以负载因子时,Hashtable也会进行扩容,但扩容规则为当前容量翻倍后加1(同样不超过允许的最大容量)。

六、其他区别

  • HashMap没有提供contains(Object value)方法,而是提供了containsValue(Object value)和containsKey(Object key)方法来检查是否包含特定的值或键。
  • Hashtable则保留了contains(Object value)方法(其功能与containsValue(Object value)相同),以及containsValue(Object value)和containsKey(Object key)方法。
  • HashMap的迭代器(Iterator)是fail-fast的,这意味着如果在迭代过程中有其他线程修改了HashMap的结构(如增加或删除元素),将会抛出ConcurrentModificationException异常。但需要注意的是,这并不是一个一定会发生的行为,它取决于JVM的实现。而Hashtable的enumerator迭代器则不是fail-fast的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值