我的理解 作下記錄,不正確的地方望不吝賜教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; }
結合源碼加別人的資料,作以下解釋: 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,移動到以前位置的倍數就能夠了,免去了從新計算位置的運算。