equals 與 hashCode

2023/10/03閱讀時間約 2 分鐘

為何要重寫equals方法

比較兩個Object是否相等時,使用equals方法

不過equals方法,預設是比較兩個物件參數所指的記憶體地址是否相同

和 "==" 兩個等號的功效是一樣的

所以我們才要重寫equals方法

讓它去比較兩個物件的內容,或我們有其他想比較兩物件的特別方式


為何要重寫hashCode方法

HashMap、HashSet這些常用的Hash開頭的Collection(集合數據結構)都會需要用到hashcode

用Object雜湊(hash)過後產生的值(hashcode)去決定應該如何儲存在集合數據結構中

例如儲存到HashMap或HashSet,以HashMap舉例

Map<String, String> map = new HashMap<>();
map.put("TW","Taiwan");
map.put("JP","​Japan");

將 [TW, Taiwan] 和 [JP, Japan] 兩對Key-Value塞入了HashMap

它背後的動作邏輯是:

  1. 將Key值進行Hash雜湊,產生一個整數值。例如字串TW雜湊後可能產生535687的雜湊值。
將產生的hash值儲存在該物件(Object)內部的一個地方。(此時就是存到字串TW中的某個地方)
存在物件(Object)內部是為了方便在之後的操作中可以快速訪問該hash值,而不需要每次都重新計算。
當然,物件的值發生改變時,會自動引用該物件的hashCode方法以重新產生新的hash值。
  1. HashMap 內部維護著一個儲存桶組(bucket array)。根據剛剛Key值產生的hash值,HashMap會將鍵值對(Key-Value)儲存到對應的儲存桶(bucket)中。
儲存桶組是一個array,每個儲存桶(bucket)可以儲存一個或以上的鍵值對(鏈表或紅黑樹)。

儲存桶組的目的是為了幫助HashMap高校地儲存與查找鍵值對。

hash值用於確定儲存位置(哪一個bucket),而bucket的索引用於實際儲存和檢索鍵值對。
儲存桶組的索引(是array,所以有索引) 是根據物件的hash值再計算得出的。
  1. 如果該bucket中已經有其他鍵值對存在,這就是發生了hash衝突。則新來的鍵值對會被添加在鏈表或紅黑樹的最末端。


注意

  • 有重寫equals方法的話,hashCode方法也一定要重寫。反過來則非必須
  • 如果兩個物件的equals方法結果為相等,則它們的hashCode方法結果也必須相同。反過來說,hashCode方法的返回結果相同,equals的結果不一定相同,因為可能是hash衝突。


最後,反正開發工具都能自動產生equals() & hashCode()

我的Java學習日記
留言0
查看全部
發表第一個留言支持創作者!