美文网首页
【HashMap】由tableSizeFor想到的一个算法

【HashMap】由tableSizeFor想到的一个算法

作者: itbird01 | 来源:发表于2022-01-18 06:47 被阅读0次

    最近在看hashmap的源码,看到一个很有意思的函数,tableSizeFor,不禁想问,这个函数到底做了什么?

        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);
        }
    

    我们先把函数源码摆上来,里面出现了几个关键的java运算符
    >>>:按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。
    | :如果相对应位都是 0,则结果为 0,否则为 1。
    清楚了运算符的作用,我们举例来说明:

    var0为7
    7的二进制: 0000 0111
    var0-1=6 : 0000 0110
    var1>>>1 : 0000 0011
    var1 |= var1 >>> 1 : 0000 0110
    var1 |= var1 >>> 2 : 0000 0111
    后续操作结果一样
    var1+1 = 8

    从这个例子中,我们得出一个结论,这个函数做了以下操作:将原操作数-1,然后将二进制的第一个1之后的所有数变为1,最后返回,操作数+1
    那这到底完成了什么功能呢?从上面的分析来看,是为了找出大于等于本身的值的最近的一个2的幂次方值,那为什么刚开始要减去一个1呢?稍等,我们通过另外一个例子说明一下

    cap 8
    0000 1000
    0000 0100 n>>>1
    ===================
    0000 1100 n|n>>>1
    0000 0011 n>>>2
    0000 1100
    ====================
    0000 1111 n|n>>>2 低位全为1,后续操作结果一样
    0000 0001 n+1
    =====================
    0001 0000 16
    cap = 15 + 1 = 16

    从这个例子上看到,如果原先操作数本身就是2的幂次方,不减去1,直接进行后续操作,那么最后+1之后,肯定会得到大于本身值的下一个2的幂次方。

    总结

    说到这里,其实大家已经看明白了,这个函数的作用就是为了找出大于等于每个输入值的,最接近的2的幂次方值。不得不说,JDK这里的这个小算法,还是设计挺巧妙的。

    相关文章

      网友评论

          本文标题:【HashMap】由tableSizeFor想到的一个算法

          本文链接:https://www.haomeiwen.com/subject/juichrtx.html