【轉】 https://blog.csdn.net/fan2012huan/article/details/51097331
首先看下該方法的定義以及被使用的地方
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;
}
public HashMap(int initialCapacity, float loadFactor) {
// code...
this.threshold = tableSizeFor(initialCapacity);
}
tableSizeFor()這個方法的作用是找到大於等於給定容量的最小2的次冪值
>>>這個符號在java里是無符號右移的意思。
接下來分析一下這個方法的作用。
第一句
int n = cap - 1;
先不用考慮,我們分析完后面的之后再回過頭來看它
然后是第二句
n |= n >>> 1;
我們這里假設n的初始值為9,那么9的二進制表示是
00000000 00000000 00000000 00001001
那么經歷一次右移之后,二進制表示是
00000000 00000000 00000000 00000100
這兩個值進行異或之后,就是
00000000 00000000 00000000 00001100
這里我們如果看最高的1的話,那么可以發現右移1位並且異或之后,使得最高位的右邊一位也是1.
同理,我們可以下一句右移2位並且異或之后,使得最高兩位1的后兩位也是1.
我們之后運行到最后一個右移,可以發現n的值變為了
00000000 00000000 00000000 00001111
當然該值大於1並且小於最大值那么+1之后,該值就變成了
00000000 00000000 00000000 00010000
驚訝的發現這個值不就是2的次冪嘛!!!
此時我們回到第一句-1,如果給定的n已經是2的次冪,但是不進行-1操作的話,那么得到的值就是大於給定值的最小2的次冪值。
至於為什么右移到16位,可以得到的最大值是32個1
11111111 11111111 11111111 11111111
這個是因為java的int類型用4個字節32位來進行存儲的。最往后沒有意義。