1.8 hashMap.resize()的 重新散列算法

7 篇文章 0 订阅
3 篇文章 0 订阅

源码
resize()的代码片段

do {
    next = e.next;
    //判断是在原数组空间还是扩容空间
    if ((e.hash & oldCap) == 0) {
        if (loTail == null)
            loHead = e;
        else
            loTail.next = e;
        loTail = e;
    }
    else {
        if (hiTail == null)
            hiHead = e;
        else
            hiTail.next = e;
        hiTail = e;
    }
} while ((e = next) != null);
if (loTail != null) {
    loTail.next = null;
    newTab[j] = loHead;
}
if (hiTail != null) {
    hiTail.next = null;
    newTab[j + oldCap] = hiHead;
}

算法原理: e.hash & oldCap == 0 放在原数组,其余的坐标+oldCap。这时只有hash在oldCap最高位的二进制为1才不能与0。这个改进算法和hash&(length-1)散列结果是一致的。

比如oldCap:16(10000),最高位就是第5位,即xxxxx1xxxx这样的hash值。这是因为10000与上任何数只能等于0或者16。

假设 oldCap(旧容量):16 newCap(新容量):32。
当hash<16时,不管扩容多少次散列值都一定在oldCap内,因为大于的16的高位一定是0。
比如 hash = 15
原大小:
01111(15) & 10000(16) =01111
扩容后:
01111(15) & 100000(32) =01111
hash&(length-1):
01111(15) & 011111(31) =01111

当hash>16时,新的散列值为原值+扩容大小,因为每扩容一次即左移1位(oldCap<<1),相当于加上2的n次方(比如oldCap=16,n就是4)
比如 hash = 31
原大小:
011111(31) & 10000(16) =01111
扩容大小:
011111(31) & 100000(32) =011111
hash&(length-1):
011111(31) & 011111(31) =011111

在进行散列运算的时候大于最高位的都是按0处理,在进行hash&(oldCap-1)运算时最高只能是oldCap-1。比如hash=31,odlCap=16 hash&(oldCap-1)=15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值