HashMap

扩容 重hash
JAVA7扩容后的rehash过程使用了单链表的头插法方式,同一位置上新元素总会被放在链表的头部位置;这样如果发生了hash冲突的话先放在一个索引上的元素终会被放到Entry链的尾部,这一点和JAVA8有区别。
JAVA8在rehash算法利用了下面的一个特性:
HashMap的扩容使用的是2次幂的扩展(指长度扩为原来2倍),所以,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置。什么意思呢? 我们举个例子说明。
假设原数组长度 capacity 为 16,扩容之后 new capacity 为 32:
下标的计算方法,对于一个 Key,如原Hash值 key1 = 0001 1001 key2 = 0000 1001
扩容前 hash & (length - 1) :
key1 : 0001 1001 & 0000 1111 -> 0000 1001
key2 : 0000 1001 & 0000 1111 -> 0000 1001
扩容后 hash & (length - 1) :
key1 : 0001 1001 & 0001 1111 -> 0001 1001
key2 : 0000 1001 & 0001 1111 -> 0000 1001
因此,我们在扩充HashMap的时候,不需要像JDK1.7的实现那样重新计算hash,
只需要看原来的hash值在扩容后新增的那一位是1还是0,如果是0的话索引没变,是1的话索引变成“原索引+oldCap
因此,我们在扩充HashMap的时候,不需要像JDK1.7的实现那样重新计算hash,
LinkedHashMap(有序,加上了双向链表)
LinkedHashMap就是HashMap+双向链表

LinkedHashMap是有序的,且默认为插入顺序
本文深入探讨了HashMap在Java7和Java8中扩容时的重hash机制差异,特别是Java8利用位运算优化了扩容过程,避免了完全重hash。同时,文章详细介绍了LinkedHashMap作为HashMap的扩展,如何通过双向链表保持元素的插入顺序。
43万+

被折叠的 条评论
为什么被折叠?



