hashMap扩容

什么时候扩容:当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值---即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。

扩容(resize):当HashMap对象内部的数组无法装载更多的元素时,对象就需要扩大数组的长度,以便能装入更多的元素。Java里的数组是无法自动扩容的,所以使用一个新的数组代替已有的容量小的数组。

resize就是使用一个容量更大的数组来代替已有的容量小的数组,transfer()方法将原有Entry数组的元素拷贝到新的Entry数组里。如果发生了hash冲突,使用单链表的头插入方式,同一位置上新元素总会被放在链表的头部位置,这样先放在一个索引上的元素终会被放到Entry链的尾部。在旧数组中同一条Entry链上的元素,通过重新计算索引位置后,有可能被放到了新数组的不同位置上。

rehash使用的是2次幂的扩展(指长度扩为原来2倍),经过rehash之后,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置

Jdk1.7 hash(){return key % table.length;}

JDK1.8的优化

                 // 原索引
51                         if ((e.hash & oldCap) == 0) {
52                             if (loTail == null)
53                                 loHead = e;
54                             else
55                                 loTail.next = e;
56                             loTail = e;
57                         }
58                         // 原索引+oldCap
59                         else {
60                             if (hiTail == null)
61                                 hiHead = e;
62                             else
63                                 hiTail.next = e;
64                             hiTail = e;
65                         }

JDK1.7中rehash的时候,旧链表迁移新链表的时候,如果在新表的数组索引位置相同,则链表元素会倒置,JDK1.8不会

 

posted @ 2017-04-14 20:00  逸风净天  阅读(891)  评论(0编辑  收藏  举报