ConcurrentHashMap中在创立时,会调用tableSizeFor办法进行计算尝试容量大小,这个办法原理就是通过奇妙的位运算,获取最靠近入参的2的幂次方数。
简略思考,如果这个数自身不是2的幂次方,如何依据这样的数,计算最靠近2的幂次方数呢?首先任意一个数,都能够示意为00...01XXX...XXX, 那么最靠近它的2幂次方数必定是最高位左移一位,低位全0,即:00...10000...000,那么如何失去这样的数呢?仔细观察发现,00...10000...000,其实就是00...01111...111+1得,所以问题就转为了如何求从最高位开始,低位全1的数,而这种数,咱们能够通过位运算+或运算失去。

   private static final int tableSizeFor(int c) {        // 减一是针对入参c恰好是二的幂次方数        // 此时经移位后输入应该还是c自身        int n = c - 1;        //通过移位加或运算,使n最终变成00...01111...111        // 移16位为止,是因为int型数据,总共32位,挪动16刚好        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;    }

举例:一个奇数
原始入参: 00...01XXX...XXX1
参数减一: 00...01XXX...XXX0
左移一位:00...001XX...XXX0
求或: 00...011XX...XXX0
左移二位: 00...00011X...XXX0
求或: 00...01111x...XXX0
...
发现法则没?每次移n位(n为2的幂次方),再与移位前的数求或,会使从高位开始的n位变成1,最终
移16位,正好变成: 00...011111...1111,此时原来的数,就变成了从高位开始全1的数,这个时候,获取最靠近它的幂次方数就非常简单了,间接加1,
变成:00...011111...1111-->00...100000...0000