HashMap中巧妙获取2的幂次

HashMap中巧妙获取2的幂次

    /**
     * Returns a power of two size for the given target capacity.
     */
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
  • 随便写一段程序打印一下:
        int cap = 102413;
        int n = cap - 1;   // 1100011
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        n |= n >>> 1;   //  1110011
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        n |= n >>> 2;   //  1111111
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        n |= n >>> 4;  //  1111111
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        n |= n >>> 8;  //  1111111
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        n |= n >>> 16;  //  1111111
        System.out.println("n:" + n + " ----- " + Integer.toBinaryString(n));
        int ret = (n < 0) ? 1 : (n >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : n + 1;

        System.out.println(ret);
        
        输出:
        n:102412 ----- 11001000000001100
        n:120846 ----- 11101100000001110
        n:130575 ----- 11111111000001111
        n:131055 ----- 11111111111101111
        n:131071 ----- 11111111111111111
        n:131071 ----- 11111111111111111
        131072
        
        小结发现一个规律:
        n |= n >>> 1;  会把原来位数中是1的位数后面的1位也置为1  //经过这一步之后,所有的1都是连续的,不会有010这样的了,
        n |= n >>> 2;  会把原来位数中是1的位数后面的2位也置为1  //经过这一步之后,所有的1都是至少4个连续的了,至少是1111这样的
        n |= n >>> 4;  会把原来位数中是1的位数后面的4位也置为1  //经过这一步之后,所有的1都是至少8个连续的了,至少是11111111这样的
        n |= n >>> 8;  会把原来位数中是1的位数后面的8位也置为1  //经过这一步之后,所有的1都是至少16个连续的了,至少是1111111111111111这样的
        n |= n >>> 16;  会把原来位数中是1的位数后面的16位也置为1  //到这一步之后,1至少是32位连续的了,而且往往来不及到这一步,前面几步骤之后就全部置1了
        
        最后返回n+1,肯定是一个2的幂次,因为全部是1的数字恰好就是比2的幂次少1;为什么要执行int n = cap - 1;这是考虑都输入刚好是2的幂次的情况,比如输入刚好是1024,如果不执行减1操作,那么输出就是2048了,减去1之后,输出还是1024
        
        上面解释了为什么返回的结果是2的幂次,因为他得到的是全1的二进制数最后加1,那么为什么刚好是大于输出参数的最小的2的幂次数呢?
        回头看看会发现,如果输入的数字位数是5位,那么这个计算的过程中并不会改变他的位数,而会得到11111,最后加1,因此得到的是大于这
        个数字的2的最小幂次数,如果输入的是11111,那运算的过程中不会改变,最后直接返回加1的结果,到这里就弄清楚了。
        
        因为计算机的位运算比较高效,因此这个方法的效率是很高的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值