if ((e.hash & oldCap) == 0)
如果返回true,表示(e.hash & (oldCap - 1))和(e.hash & (newCap - 1))的结果是相同的
因为Map容量必须是2次幂,并且翻倍扩容,所以oldCap和newCap是2的次幂,
并且newCap是oldCap的两倍,就相当于oldCap的唯一一个二进制的1向高位移动了一位 (16 << 1)
默认容量是16,那么就相当于e.hash & 0x1111 (oldCap - 1 = 15),
现在容量扩大了一倍,就是32,那么rehash定位就等于e.hash & 0x11111 (newCap - 1 = 31)
数组每次扩容都是原来的两倍,所以每一个元素在新数组中的位置要么是原来的index,要么index = index + oldCap
假设数组长度:2,key:3
0 0 0 1
0 0 1 1
结果为 0 0 0 1 = 1 所以数组下标为1;
扩容后,数组长度:4,key:3
0 0 1 1
0 0 1 1
结果为 0 0 1 1 = 3 = 原来的index + oldCap = 1 + 2
即确定元素在新数组的下标时,我们只需要检测元素的hash值与oldCap作与操作的结果是否为0
0,那么下标还是原来的下标;
1,那么下标等于原来下标加上旧数组长度
本文详细解析了哈希表在进行扩容时元素重新分布的计算逻辑。通过对比新旧容量的二进制位运算,解释了如何判断元素在扩容后的哈希表中是保持原位置还是移动到新位置。
1万+

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



