巧妙位运算

HashMap初始化大小时的巧妙位运算

   我们知道HashMap会保证其大小等于2的幂次方,也就是二进制只有一位为1,因为这可以使得它进行求余运算的时候可以使用&(length-1),扩容resize的时候还可以使用&oldLength,这些位运算可以加快map的插入和扩容速度
   那么如果我们在实例化对象的时候设置它的大小,它会怎么求呢?
   本来我并没有留意的,但是有一次做题,它说使用位运算求一个>=n的2次幂,让我想起了HashMap,然后看了一下源码,vocal,二进制太巧妙了吧
位运算求2^m(min)>=n
我们可以根据代码猜出作者的思路
首先求一个>=n的最小2的幂,有两种情况:

  1. 2^m>n
  2. 2^m=n

我们先考虑第一种情况,2^m肯定在n最高位1的前一位(第m+1位),
如果第1->m位全是1,那么加1就可以得到2^m,
我们如果使得n进行位运算之后变成m+1位后全1,我们无需考虑其他位置上的值,因为我们知道第m位是1,保证能通过第m位1能得出全1就行,根据代码第一步位运算n=n|n>>>1,使得前两位都是1,第二步前四位,以此类推,因为int就32位,所以只需要运算到>>>16,结果就是2^m-1,加1之后得到 2^m
如果是第二种情况呢?本来就是2^m的话直接按上一种情况操作结果会变成 2^(m+1),所以我们要先减1,让第一位1后移一位,减1对第一种情况没有影响,所以就得出了上面的结果

因为使用的是二进制,所以关于2的运算都可以使用位运算变得很巧妙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值