关于HashMap中tableSizeFor的见解

  • 今天学了一下关于HashMap的底层实现原理。
  • 我们看到这一段代码:
static final int tableSizeFor(int var0) {
        int var1 = var0 - 1;
        var1 |= var1 >>> 1;
        var1 |= var1 >>> 2;
        var1 |= var1 >>> 4;
        var1 |= var1 >>> 8;
        var1 |= var1 >>> 16;
        return var1 < 0 ? 1 : (var1 >= 1073741824 ? 1073741824 : var1 + 1);
}
  • 这道代码的作用是啥呢,他的作用就是取最接近var0这个数的2的幂次
  • 例如:4最接近的2的幂次其实就是4,即2^2; 5最接近的2的幂次的为8(2^3).
  • 按我们正常的思路:枚举一遍复杂度为O(30).这里最大值为2^30.
  • 那我们来解释一下上面代码是怎么实现的。

int var1 = var0 - 1; 这里是为了防止var0本身就是2的幂次,如果按下面的方法的话最后结果是var0*2.

  • 其实重点还是下面这几句。

var1 |= var1 >>> 1; //取高位的1个1
var1 |= var1 >>> 2; //取高位的2个1
var1 |= var1 >>> 4; //取高位的4个1
var1 |= var1 >>> 8; //取高位的8个1
var1 |= var1 >>> 16; //取高位的16个1

  • 其实这里我们不需要关心var1的低位是0还是1,我们只需要关注var1的高位的1即可。
举个例子:我们随便取个数,只关注这个数高位的1即可。
假设这个数的最高位一开始在第32bit.
即
1000 0000 0000 0000 0000 0000 0000 0000 (该数的其他bit是0还是1我们不管)
var1>>>1为:
0100 0000 0000 0000 0000 0000 0000 0000
经过var1 |= var1 >>> 1 //取高位的1个1  就变成了
1100 0000 0000 0000 0000 0000 0000 0000 //现在变成了两个1
 经过var1 |= var1 >>> 2;  //取高位的2个1 就变成了
1111 0000 0000 0000 0000 0000 0000 0000 //变成了4个1
以此类推,
取4个1
1111 1111 0000 0000 0000 0000 0000 0000
8个1
1111 1111 1111 1111 0000 0000 0000 0000
16个1
1111 1111 1111 1111 1111 1111 1111 1111 
这样我们就把32个bit全部替换成1了
最后加1就变成
0001 0000 0000 0000 0000 0000 0000 0000 0000
其他的数的计算过程也是如此,我们只关心var当前高位有多少个1即可。
  • 其他的数你也可以在纸推导几次,大概就明白tableSizeFor这段代码的含义的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值