【HashMap扩容相关的蛛丝马迹】位运算与取模的奇妙关系

给定一个数保证输出一定是大于输入值的2的最小幂

  • HashMap的tableSizeFor实现了这个函数,下面是细节解析
    static final int tableSizeFor(int cap) { //假设传入3和4
    	//这里-1是为了防止cap已经是2的幂时得到cap*2的结果
        int n = cap - 1; //3变2   4变3
        //这里2的二进制就是10 | 01 也就变成了二进制的11十进制是3
       	//同样3的二进制是11 | 01 还是 11 
        n |= n >>> 1;
        //这里2的二进制就是10 | 01 也就变成了二进制的11十进制是3
       	//同样3的二进制是11 | 01 还是 11 
       	//此时传入的2变成了3,4也变成了3
       	//后续操作是针对cap较大时的操作,可以省略掉
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1
        /*神奇的地方,二进制中位全为1的数再加1就是2的幂*/;
    }

应用场景

希望只有一个 i & n就可以实现模运算的场景
例如netty的EventLoop分配
例如HashMap的hash查找分配

更多

(1)思考一下如果我希望hashmap可以一边被我遍历还一边扩容,我该怎么去递增table数组的索引?如果是缩容呢?
(2)HashMap每次扩容都是2的幂那岂不是很浪费?这样做难道仅仅因为为了优化一个取模运算?(引出平摊分析)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值