tableSizeFor方法

/**
 * 根據(jù)容量參數(shù),返回一個2的n次冪的table長度。
 */
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;
}

先看一下tableSizeFor()的輸入與輸出

public static void main(String[] args) {
    System.out.println(tableSizeFor(1));
    System.out.println(tableSizeFor(5));
    System.out.println(tableSizeFor(25));
    System.out.println(tableSizeFor(125));
    System.out.println(tableSizeFor(625));
}

輸出:
1
8
32
128
1024

通過輸出可以大致猜到tableSizeFor的作用是返回一個大于輸入?yún)?shù)且最小的為2的n次冪的數(shù)。

我們再來看看是怎么做到的。

當輸入為25的時候,n等于24,轉(zhuǎn)成二進制為1100,右移1位為0110,將1100與0110進行或("|")操作,得到1110。接下來右移兩位得11,再進行或操作得1111,接下來操作n的值就不會變化了。最后返回的時候,返回n+1,也就是10000,十進制為32。按照這種邏輯得到2的n次冪的數(shù)。

再來看一個例子,當n=1<<30的時候:

01 00000 00000 00000 00000 00000 00000 (n)   
01 10000 00000 00000 00000 00000 00000 (n |= n >>> 1)    
01 11100 00000 00000 00000 00000 00000 (n |= n >>> 2)    
01 11111 11000 00000 00000 00000 00000 (n |= n >>> 4)    
01 11111 11111 11111 00000 00000 00000 (n |= n >>> 8)    
01 11111 11111 11111 11111 11111 11111 (n |= n >>> 16)    

由于int類型為32位,所有即使除符號為之外只有第一位為1的情況,也能將所有的位全部變成1,不過由于最后計算出來為int類型的最大值,此時返回n+1會導致溢出,不能返回期望的結(jié)果,這也是為什么在方法開始是要執(zhí)行int n = c - 1;的原因。

那么又有一個問題,為什么要在前面減1,然后在后面加回來呢?當輸入為0的時候就會發(fā)現(xiàn),方法的輸出為1,HashMap的容量只有大于0時才有意義。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容