首先 index 如何计算
我们都知道添加一个Entry 进 Map其实就是添加一个不可重复的 key 进入散链表中,
在计算的时候 首先会获取到 index 的 hash 值 而 hash 值是一个 int 范围内的整数, 而 index 值的范围只能是 在 0 到 cap (筒子个数减一)
那么就需要将 hash 值缩小 ,通过取余的形式缩小 ,hashmap 是通过 key.hash() & cap 等价于 key.hash() % cap ,此时 index 的值便被计算出
在计算机中 位运算是 远远快于 算数运算的
那么接下来还有一个问题,当扩容后旧值是如何处理的,旧值的新位置在扩容后的哪个桶中
扩容是如何计算新桶的位置的
判断 key.hash()& oldcap.size() 是否为 0
为 0 则证明 key.hash()的值小于 oldcap.size() ,那么自然之前在哪个筒子 现在也在哪个筒子
不为 0 则证明 key.hash() 的值 大于 oldcap.size(),此时此key 的新位置就是 旧 index + oldcap.size();
举例说明 比如之前的桶是 16 个 扩容后是 32 个 (由于 hashmap 扩容是 2 的指数倍 所以可以这样计算)
之前的 hash 值的 7 那么 7 & 16 = 0 , 并且 7&(16 -1) = 7 , 7&(32 - 1 ) = 7
之前的 hash 值是 17 那么 17 & 16 = 1,并切 17 & (16 -1 ) = 1, 17 &(32 -1 ) = 17 , 17 = 1 - 16(oldcap)
也就是 扩容后 将桶分为地位和高位 ,之前在地位的 且 hash 值没有 oldcap 大的 还在低位 ,hash 值比 oldcap 大的 那么 新位置就是 旧 index + oldcap
那么在扩容后查新值的时候 ,计算的hash 值是不变的 ,但是取模的时候 基数已经是 (现有筒子的个数 -1) ,同样 index 值还是可以被正确的取到的
汲取地址 https://blog.csdn.net/qq_37155154/article/details/115161022
标签:index,hash,HashMap,17,16,旧值,key,oldcap From: https://www.cnblogs.com/haodongshuai/p/16786592.html