java的hashMap扩容新地址计算的巧妙

2022/6/2 1:22:01

本文主要是介绍java的hashMap扩容新地址计算的巧妙,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

what:

  hashmap扩容

    1、重新建立一个新的数组,长度为原数组的两倍(实际长度为2的n次幂);

    2、遍历旧数组的每个数据,重新计算每个元素在新数组中的存储位置(一次性完成);使用节点的hash值与旧数组长度进行位与运算,如果运算结果为0,表示元素在新数组中的位置不变;否则,则在新数组中的位置下标=原位置+原数组长度。

 

why:

  为什么扩容时节点重 hash 只可能分布在原索引位置或者 原索引长度+oldCap 位置呢?换句话说,扩容时使用节点的hash值跟oldCap进行位与运算,以此决定将节点分布到原索引位置或者原索引+oldCap位置上的原理是什么呢?

  

  假设老表的容量为16,则新表容量为16*2=32,假设节点1的hash值为 0000 0000 0000 0000 0000 1111 0000 1010,节点2的hash值为 0000 0000 0000 0000 0000 1111 0001 1010。

  那么节点1和节点2在老表的索引位置计算如下图:

    计算1(16个桶的真实计算),由于老表的长度限制,节点1和节点2的索引位置只取决于节点hash值的最后4位。

    计算2(32个桶的真实计算,扩容1倍后),计算2为元素在新表中的索引计算,可以看出如果两个节点在老表的索引位置相同,则新表的索引位置只取决于节点hash值倒数第5位的值,而此位置的值刚好为老表的容量值16,此时节点在新表的索引位置只有两种情况:原索引位置和 原索引+oldCap(放大1倍)位置(在此例中即为10和10+16=26)。

    由于结果只取决于节点hash值的倒数第5位,而此位置的值刚好为老表的容量值16,因此此时新表的索引位置的计算可以替换为计算3,直接使用节点的hash值与老表的容量16进行位于运算,如果结果为0则该节点在新表的索引位置为原索引位置,否则该节点在新表的索引位置为 原索引+ oldCap 位置。

 



这篇关于java的hashMap扩容新地址计算的巧妙的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程