1. 程式人生 > >HashMap中的equals和hashCode

HashMap中的equals和hashCode

HashMap的儲存方式

HashMap的實現方式是陣列鏈,不同的物件根據其雜湊碼(hashCode方法的返回值)找到對應的陣列下標,然後存入陣列。不同的物件有相同的雜湊碼時怎麼辦?這就由陣列鏈中的鏈來解決了,相同雜湊碼的物件都放在同一條鏈上,該鏈的鏈頭指向陣列,進而形成陣列鏈。


當第一個物件已經存入HashMap,第二個物件準備存入HashMap時,系統在查詢到陣列下標後若發現它們的hashCode相同(也就是衝突),會呼叫equals()來檢查它們之間的關係,會有相應有以下兩種處理方法: 
1. 如果相等,系統就覆蓋第一個物件; 
2. 如果不等,系統視它們為純粹的下標衝突,將它們放在同一條鏈上;

如果它們的hashCode不相同,直接存入第二個物件。

equals()匹配但hashCode()不同

現在假設有兩個物件,它們的equals()相匹配,但hashCode()卻不同,讓我們好好分析一下當它們存入HashMap時會發生什麼。

假設StringA和StringB是兩個不同的物件,內容都是”hello,world”,equals()返回true,但hashCode()返回值不一樣。我們把StringA和StringB當作Key,分別對應著ValueA和ValueB。

在StringA和ValueA已經存入HashMap後,我們嘗試存入StringB和ValueB,因為hashCode不同,StringB和ValueB順利地進入HashMap.

我們寫一個查詢:HashMap.get(“hello,world”),此時會發生什麼呢?我們取回的究竟是ValueA還是ValueB?只有天知道。

或者換一下,我們寫一個查詢:HashMap.get(StringA),此時會發生什麼呢?我們取回的究竟是ValueA還是ValueB?只有天知道。

再換一下,我們寫一個查詢:HashMap.get(StringB),此時會發生什麼呢?我們取回的究竟是ValueA還是ValueB?只有天知道。

相信聰明的你已經看出了問題所在。所以我們常說,如果equals匹配,hashCode()一定要相同,不然就有神奇的事情發生。


HashMap是執行緒不安全的,執行緒安全要用ConcurrentMap。