HashMap 中的哈希值計算問題


date: 2020-08-21 16:48:00
updated: 2020-08-21 16:52:00

HashMap 中的哈希值計算問題

1. hash 計算

JDK1.8
HashMap源碼

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

右移16位相當於將高16位移入到低16位,再與原hashcode做異或計算(位相同為0,不同為1)可以將高低位二進制特征混合起來 => 高16位沒有發生變化,但是低16位改變了

拿到的hash值會參與hashmap中數組槽位的計算,計算公式:(n - 1) & hash,假設數組初始槽位16個,那么槽位計算如下:

高區的16位很有可能會被數組槽位數的二進制碼鎖屏蔽,如果我們不做剛才移位異或運算,那么在計算槽位時將丟失高區特征

雖然丟失了高區特征,不同hashcode也可以計算出不同的槽位來,但是如果兩個hashcode很接近時,高區的特征差異可能會導致一次哈希碰撞。

2. 使用異或運算的原因

異或運算能更好的保留各部分的特征,如果采用 & 運算計算出來的值會向0靠攏,采用 | 運算計算出來的值會向1靠攏

3. 為什么槽位數必須使用2^n / 為什么要 &length-1

為了讓哈希后的結果更加均勻,減少hash碰撞

4. 擴容后Hash值計算

length * 2,即新增的bit位是1,在 (n - 1) & hash 時,只需要判斷新增加的這一個bit位,如果是0的話,說明索引不變,如果變成1了,索引變成 原索引+擴容前的容量大小


免責聲明!

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



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