jdk 1.7
1.实现原理:数组+链表。
- 当存入键值对时,先判断数组是否为空,如果为空则进行第一次扩容。
- 先通过hash获得一个hashcode,对应存放的位置,如果HashMap中这个位置没有存放键值对,就直接存入。
- 如果该位置存有数据,且key已经存在,直接覆盖值。
- 如果该位置存有数据,且key不存在则将数据链到链表末端(拉链法)。
缺点:大量数据累积会使得链表增长,查询效率会越来越低
不安全
在jdk1.7 中,当需要调整HashMap的容量时,采用的时头插法,若同一时间有两个线程对其进行调整,那么就会造成竞争,形成循环链表,造成死循环。
jdk 1.8
1.实现原理:数组+链表+红黑树
区别是:在jdk1.8中,当链表的长度到达一个阈值(8)时,链表会转换成红黑树,这样就增加了效率。
不安全
在jdk 1.8 中,HashMap依旧是线程不安全的,当两个线程同时操作时,会造成数据覆盖的情况,两个线程同时对HashMap进行判断,之后存放值有先后,那么之前的值就会被覆盖掉。
在jdk 1.8 中,链表与红黑树转换之前,还会先判断一下数组的容量,如果数组的容量没有达到阈值(64),则会先扩容,再转换。
说到这里,就不得不说一下HashMap的扩容机制:
HashMap的扩容与否,主要与其负载因子(默认为0.75)有关,0.75即表示数据量为目前容量的0.75,当达到阈值之后,则会以2的次方进行扩充。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探