tableSizeFor
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;
}
分别右移位1,2,4,8,16的原因分析:
比如:cap不是2的幂次数值,考虑一种极端情况。
cap=2^30+1=1073741825 其2进制数为:0100 0000 0000 0000 0000 0000 0000 0001
int n = cap - 1; n = 1073741824,其二进制为:0100 0000 0000 0000 0000 0000 0000 0000
第一步:n >>>1 , 其二进制为:0010 0000 0000 0000 0000 0000 0000 0000
或运算之后:n |= n >>> 1;
n: 0100 0000 0000 0000 0000 0000 0000 0000
n >>>1: 0010 0000 0000 0000 0000 0000 0000 0000
n |= n >>> 1:0110 0000 0000 0000 0000 0000 0000 0000
第二步:n >>>2,此时n=0110 0000 0000 0000 0000 0000 0000 0000
无符号右移后,0001 1000 0000 0000 0000 0000 0000 0000
或运算之后:n |= n >>> 2;
n: 0110 0000 0000 0000 0000 0000 0000 0000
n >>>1: 0001 1000 0000 0000 0000 0000 0000 0000
n |= n >>> 2:0111 1000 0000 0000 0000 0000 0000 0000
第三步:n >>>4,此时n=0111 1000 0000 0000 0000 0000 0000 0000
无符号右移后,0000 0111 1000 0000 0000 0000 0000 0000
或运算之后:n |= n >>> 4;
n: 0111 1000 0000 0000 0000 0000 0000 0000
n >>>1: 0000 0111 1000 0000 0000 0000 0000 0000
n |= n >>> 4:0111 1111 1000 0000 0000 0000 0000 0000
第四步:n >>>8,此时n=0111 1111 1000 0000 0000 0000 0000 0000
无符号右移后,0000 0000 0111 1111 1000 0000 0000 0000
或运算之后:n |= n >>> 8;
n: 0111 1111 1000 0000 0000 0000 0000 0000
n >>>1: 0000 0000 0111 1111 1000 0000 0000 0000
n |= n >>> 8:0111 1111 1111 1111 1000 0000 0000 0000
第五步:n >>>16,此时n=0111 1111 1111 1111 1000 0000 0000 0000
无符号右移后,0000 0000 0000 0000 0111 1111 1111 1111 1
或运算之后:n |= n >>> 16;
n: 0111 1111 1111 1111 1000 0000 0000 0000
n >>>1: 0000 0000 0000 0000 0111 1111 1111 1111 (1)舍掉
n |= n >>> 16:0111 1111 1111 1111 1111 1111 1111 1111
最后一步,n+1=1000 0000 0000 0000 0000 0000 0000 0000=2^31
如果cap不是一个2的幂次方数值,则得到大于cap的第一个2的幂次方数。
该方法之所以右移位这么多次,正是为了处理这种极端情况。如上述运算流程可得出结论,该方法得到的值,必定为2的幂次数值,右移的作用的是将0填补为1。
以上是我个人浅显的理解,如有问题,敬请指正。