Java集合--tableSizeFor

在看 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倍。二進制

相關文章
相關標籤/搜索