Java 中 HashMap 和 Hashtable 的联系
创始人
2024-11-16 17:35:51
0次

目录

相同

不同

1. 继承的父类不同

2. 线程安全性不同

3. 包含的 contains 方法不同

4. toString方法不同

5. 是否允许null值不同

6. 计算hash值的方式不同

7. 计算索引位置的方法不同

8. 初始化容量不同

9. 扩容方式不同

10. 内部存储策略不同(此处讨论的是Java 8)

11. 支持的遍历种类不同

12. 迭代器不同


相同

HashMap 和 Hashtable 都实现了 Map、Cloneable、Serializable接口

不同

1. 继承的父类不同

HashMap 继承自 AbstractMap 类;

Hashtable 继承自 Dictionary 类,Dictionary 类是一个已经被废弃的类,因此已经几乎没人用Hashtable 了。

2. 线程安全性不同

HashMap 线程不安全。HashMap 中的方法在一般情况下是非 Synchronize 的。使用 HashMap 时就必须要自己增加同步处理;

Hashtable 线程安全,内部方法大多是 Synchronize 的。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步。

Hashtable 实现线程安全的代价就是效率变低,因为会锁住整个 Hashtable,而ConcurrentHashMap 做了相关优化,因为 ConcurrentHashMap 使用了分段锁,并不对整个数据进行锁定,效率比 Hashtable 高很多。

3. 包含的 contains 方法不同

HashMap 是没有 contains 方法的,只包括 containsValue 和 containsKey 方法;

Hashtable则保留了 contains 方法,效果同 containsValue,还包括 containsValue 和 containsKey方法。

4. toString方法不同

HashMap没有重写toString()方法;

Hashtable重写了toString()方法。

5. 是否允许null值不同

HashMap 是允许 key 和 value 为 null 值的,用 containsValue 和 containsKey 方法判断是否包含对应键值对;

Hashtable 键值对都不能为空,会报空指针异常。

6. 计算hash值的方式不同

HashMap 内部专门使用了名为 hash 的方法来对 key 的 hash 值做出进一步处理:
(h = key.hashCode()) ^ (h >>> 16),将计算出的值作为最终的 hash 值。目的是为了获得一个更加均匀分布的整数,以便哈希函数得出的地址更加均匀分布,降低冲突概率;

Hashtable 则是直接使用 key.hashCode() 作为最终的 hash 值。

static final int hash(Object key) {     int h;     return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }

7. 计算索引位置的方法不同

HashMap 在求 hash 值对应的位置索引为:index = (n - 1) & hash,这样的取模操作只需要做位运算,位运算比除法的效率要高很多;

Hashtable:int index = (hash & 0x7FFFFFFF) % tab.length;&0x7FFFFFFF的目的是为了将负的hash 值转化为正值,因为 hash 值有可能为负数,而 &0x7FFFFFFF 后,只有符号位改变,而后面的位都不变。

8. 初始化容量不同

HashMap 的初始容量为:16

Hashtable 初始容量为:11

但是两者的负载因子默认都是:0.75。

9. 扩容方式不同

HashMap:为原容量的2倍,而且扩容结果一定是2的幂次数;

Hashtable:为原容量2倍加1。

10. 内部存储策略不同(此处讨论的是Java 8)

HashMap:满足链表长度大于等于 8并且数组长度大于等于64时,链表转变成红黑树;当红黑树节点少于6时,退化为链表;

Hashtable:都是以链表方式存储。

11. 支持的遍历种类不同

HashMap 只支持Iterator遍历;

Hashtable 支持Iterator和Enumeration两种方式遍历。

12. 迭代器不同

HashMap 的迭代器(Iterator)是 fail-fast 迭代器;

Hashtable 的enumerator迭代器不是fail-fast的。

所以当有其它线程改变了 HashMap 的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的 remove() 方法移除元素则不会抛出ConcurrentModificationException 异常。但这并不是一个一定发生的行为,要看 JVM 。而Hashtable 则不会。

本文参考了下述两篇文章:

HashMap和Hashtable的区别(绝对经典)_hashmap hashtable-CSDN博客

HashMap和Hashtable的区别-CSDN博客

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...