在看 HashMap 源碼的時候有這麼一段代碼java
private static final int MAXIMUM_CAPACITY = 1 << 30; private static final int tableSizeFor(int c) { int n = c - 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; }
第一眼看上去徹底看不懂,這幾個右移按位或是什麼意思code
運行一個例子看看blog
private static final int MAXIMUM_CAPACITY = 1 << 30; private static int tableSizeFor(int c) { int n = c - 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 static void main(String[] args) { System.out.println(tableSizeFor(6)); System.out.println(tableSizeFor(7)); System.out.println(tableSizeFor(10)); System.out.println(tableSizeFor(15)); System.out.println(tableSizeFor(18)); } // 輸出 8 8 16 16 32
輸入6,7 都是輸出8源碼
輸入10, 15 輸出16hash
輸入18 輸出32table
輸出的都是2的指數冪,其實這個方法是用於找到大於等於輸入參數的的最小的2的指數冪。爲何須要這樣的方法,由於hashmap的容量大小都是2的指數冪。class
以輸入22爲例子, n = c - 1, n 爲 21hashmap
每一次右移以後與上一次的結果作按位或操做(只要有一個位是1,結果就是1),經過幾回操做以後將本來二進制最高位爲1的後面幾位所有至1,最後再加1,獲得一個2的指數冪。map
至於爲何一開始要執行 n = c - 1; 這是爲了防止 c 已是2的冪,若是 c 已是2的冪, 又沒有執行這個減1操做,則執行完後面的幾條無符號右移操做以後,返回的結果將是這個c的2倍。二進制