【HashMap,HashTable,ConcurrentHashMap的共同点和区别】
1.三者简述
HashMap:是Map的衍生,也是map接口的实现类,底层为:数组+链表实现(1.8加入了红黑树),以键值对的形式存储,根据hash函数来实现映射关系,HashMap用Key的哈希值来存储和查找键值对。当插入一个value时,HashMap会计算Key的哈希值然后把value和这个哈希值相关联。
他的key和value可以为null;
它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
HashTable:底层:数组+链表实现,继承自Dictionary类,并且和Hashmap一样,都是map的实现类,很多映射的常用功能与HashMap类似,但是它是线程安全的,任一时间只有一个线程能写Hashtable,而且其key和value不能为null;并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。
ConcurrentHashMap:底层为数组+链表+红黑树(1.8),ConcurrentHashMap的key和Value都不能为null,继承自抽象类AbstractMap,而AbstractMap则是Map接口的实现类,它是线程安全的。和HashMap功能基本一致,主要是为了解决HashMap线程不安全问题。
2.大致区别
key-value | 线程安全 |
默认大小(初始size)和扩容 |
extends/implement | 底层实现 | |||
HashMap | 均可为null | 线程不安全 |
初始size=16, 扩容:newsize = oldsize*2 |
是Map接口的实现类 |
1.8中是数组+链表+ 红黑树 |
||
HashTable | 均不可为null | 线程安全 |
初始size为11, 扩容:newsize = olesize*2+1 |
继承自Dictionary类, 也是Map接口的实现类 |
数组+链表 | ||
ConcurrentHashMap | 均不可为null | 线程安全 |
初始size为16, 扩容:当数组存储的元素的数 量大于阈值就会进行扩容; 阈值也就是0.75*数组长度, 也就是段内元素超过该段对应 Entry数组长度的75%触发扩容 ,不会对整个Map进行扩容 |
继承自抽象类 AbstractMap, Map接口的实现类 |
底层为数组+链表+ 红黑树(1.8) |
3.关于多线程安全
-03-15更
hashmap为线程不安全,简单总结就是在链表中使用头插法可能会出现死循环(1.8前),也可能会因为判定无hash碰撞直接插入元素出现数据覆盖(1.8)
hashtable为线程安全,因为它把整个hash表都加了同步锁synchronized,这样虽然安全但效率很低
concurrent为线程安全,它使用分段锁,一次锁住一个桶。ConcurrentHashMap默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁住当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的
参考:https://blog.csdn.net/heting717/article/details/103868691
https://www.cnblogs.com/heyonggang/p/9112731.html
https://www.jianshu.com/p/19864e6c126f
并感谢小猴同学的指点@_@
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统