hashmap 爲何初始化容量是2的冪次方

我的理解 作下記錄,不正確的地方望不吝賜教node

這是hashmap初始化容量時候 對容量大小作的處理,保證初始化容量爲最近的2的冪次方(JDK1.8)數組

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;
}

思考,爲啥非得是2的冪次方 ,2的倍數不行麼,奇數不行麼?

結合源碼加別人的資料,作以下解釋:
   1.奇數不行的解釋很能被接受,在計算hash的時候,肯定落在數組的位置的時候,計算方法是(n - 1) & hash ,奇數n-1爲偶數,偶數2進制的結尾都是0,通過&運算末尾都是0,會增長hash衝突。
   2.爲啥要是2的冪,不能是2的倍數麼,好比6,10?
       2.1 hashmap 結構是數組,每一個數組裏面的結構是node(鏈表或紅黑樹),正常狀況下,若是你想放數據到不一樣的位置,確定會想到取餘數肯定放在那個數據裏, 
                         計算公式: hash % n,這個是十進制計算。在計算機中,  (n - 1) & hash,當n爲2次冪時,會知足一個公式:(n - 1) & hash = hash % n,計算更加高效。
       2.2 只有是2的冪數的數字通過n-1以後,二進制確定是  ...11111111  這樣的格式,這種格式計算的位置的時候,徹底是由產生的hash值類決定,而不受n-1 影響。你可能會想,受影響不是更 
             好麼,又計算了一下 ,hash衝突可能更低了,這裏要考慮到擴容了,2的冪次方*2,在二進制中好比4和8,表明2的2次方和3次方,他們的2進制結構類似  0000 0100       0000 1000   
              只是高位向前移了一位,這樣擴容的時候,只須要判斷高位hash,移動到以前位置的倍數就能夠了,免去了從新計算位置的運算。
相關文章
相關標籤/搜索