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;
}
这段代码的作用就是找到第一个大于等于cap且是2的次幂的数,当然结果不会大于MAXIMUM_CAPACITY。
举个例子假设极限情况下cap为010000001
n=cap-1=010000000 除了最高位全是0,
n>>>1=00100000,
n|=n>>>1
01000000
00100000
01100000
后面一位就刷成1了,
继续n>>>2 = 00011000
n|=n>>>2
01100000
00011000
01111000
继续往后两位刷成1,加上第一步1位一共3位被刷成1
n|=n>>>4继续往后四位刷成1,到这步共7位刷成1,
n|=n>>>8继续往后刷8位,已经刷了15位了,
n|=n>>>16继续往后刷16位,到这步总共应该刷了31位,又因为n最大值不会超过1>>>30,也就是n最大不会超过30位,到这就可以确定全部刷1了,样例中的最后结果为01111111,最后在加上1,
结果为10000000就是2的n次方了。
注:上述二进制都省略了高位的0
为啥要n-1之后再计算,举个简单的例子假如n为01010101,最后得到到结果没问题10000000,但是如果n为100000,它原本就是2的次幂(2的5次幂),可以直接返回,但是经过上述一系列操作就变成1000000(2的6次幂)。
简单总结一下这n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n+=1,
这一系列的或,右移操作其实就是将原数二进制位中的0赋值为1,最后在加1就相当于原数除了最高位全部赋0,然后左移一位。