/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
将传入的容量减去1,这是为了在传入诸如16,32这样2的幂时,不会在计算过后变成32,64这样的数,可以减少空间浪费。下方的分析只针对正数
int n = cap - 1;
将n右移一位后做或等运算,此时原本的二进制数n第一个1的位置后会多一个1。
此时可举出一个极端例子,即一个二进制数只有从右往左第31个数为1,其他数为0
n的原数 | 0100...0 | |
右移一位 | 0010...0 |
|
或等运算后 | 0110...0 | 此时或等运算后第一个1copy了一个到第一个1后面,此时这个二进制数中就有了两个1 |
第二次运算时,将上方运算后的数右移两位并且进行或等运算 | 011110...0 | |
第三次运算,将上方已经有四位为1的二进制数右移四位并且进行或等运算 | 0111111110...0 | |
以此类推,第四次需要右移8位,第五次右移16位,最终运算出来 | 01..(一共31个1)..1 | 这个数也就是2的31次方减一,int的最大数。总而言之,这一系列的右移或等运算就是为了将一个二进制数从第一个为1的位开始到最后一位都填充上1,得出一个2的x次幂-1的数 |
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
上方的运算可以运算出大于等于传入容量小于等于最大int数的2的x次幂数,
运算完后校验n是否小于0,若是小于0则容量设为1,若n大于最大容量(MAXIMUM_CAPACITY = 1 << 30)则返回最大容量,否则返回n+1。返回的这个数也就是一个2的幂
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
这个方法将传入的容量转化为2的幂(也就是说二进制数中只有一位是1),返回的值必须大于等于当前传入容量,例:cap=10,将返回16,cap=17将返回32。Intresting!