hashmap 為什么初始化容量是2的冪次方


個人理解 做下記錄,不正確的地方望不吝賜教

這是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進制結構相 似,比如
            4和8   00000100    0000 1000   只是高位向前移了一位,這樣擴容的時候,只需要判斷高位hash,移動到之前位置的倍數就可以了,免去了重新計算位置的運算。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM