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的次方进行扩充。
浙公网安备 33010602011771号