MyHashMap
return h % M;
為了避免hash碰撞,我們將M往往設置成質數,避免由於鍵在某一范圍比較集中所致大量的hash碰撞
如:當h值集中100-120,但是M取了100,這樣hash所得值集中在0-20。
HashMap中的indexFor(jdk1.7)
默認值M為16
return h & (M - 1);
-
等效取余
M取值往往為2的冪次方,而M-1會產生低位全為1的情況,使得&運算結果小於M -
運算效率提高
%運算的效率低於位運算 -
碰撞問題
產生大量碰撞的情況:
二進制來看,參數key中M個低位常出現同一值。如M為4,而M-1其二進制為:1111
參數key中的低位出現同一值,如:00001110,00101110,01001110
但由此而言,產生hash碰撞的數據相差之間較大。 -
2的冪次的原因
保證小於M的每個值都可以取到
HashMap中的hash函數
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
- hashCode()返回值是32位,>>>意為右移16位,即為去返回值中的高16位
- ^:亦或運算,使用疑惑的原因是異或的真值表中1,0的比例相同為1/2,hash碰撞減少,更為散列
- 注意:null的返回值是0,但只能存在一個鍵為null的鍵值對(非null的對象hash不一定不為0,f5a5a608的hash值為0)