Java中HashMap的hash分佈策略的簡單解釋

趴源碼是看到一段難以想象的代碼,網上的解釋彷佛不大使人滿意,所以稍微花點時間解讀了一下,若有錯誤請指正java

HashMap的桶是這樣搞的性能

// 片斷1
static final int hash(Object key) { 
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 片斷2
int n = tab.length;
int index = (n - 1) & hash;

index就是最後獲得下標,代碼很簡潔,但問題不少spa

Q1.我知道&使得index<=min(n-1,hash),但爲何用&不用mod?code

A1.n-1是2^m-1,等價於hash mod 2^m = hash mod n,用&和%徹底一致,而且&更快,所以沒有用%的理由源碼

Q2.我是說你這樣&有什麼用?hash

A2.只要保證hash分佈足夠均衡,也保證了hash後幾位也足夠均勻,那idx的分佈在長度範圍內也是分佈均勻的class

Q3.高16位異或有什麼用?方法

A3.由Q1咱們知道idx取決於hash的後log10(n)+1長度的數值分佈,那問題來了,當n自己較小時,高位等價於被截斷,hash的意義存在侷限性(想象一下多個數高位不一樣低位相同的衝突),所以須要高位的運算參與,儘量知足最後結果的分佈均勻高性能

Q4.那高16位參與運算咋不用&、|?static

A4.首先,若是使用&,當長度大於\(2^{16}\)時高16位將所有置零,也就是說空間徹底被浪費(你永遠算不到那裏),下一個|是處於0和1的機率分佈而言,1出現的可能比0高得多,也不是好方法

Q5.這樣哈希並不必定很靠譜啊?

A5.確實,但源碼內部的註釋有說明到,因爲已經採用了大量哈希碰撞時交由紅黑樹處理的策略,所以這裏的哈希策略只是高性能下比較好的實現,而非嚴謹的實現

相關文章
相關標籤/搜索