為何要重寫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
它背後的動作邏輯是:
- 將Key值進行Hash雜湊,產生一個整數值。例如字串TW雜湊後可能產生535687的雜湊值。
將產生的hash值儲存在該物件(Object)內部的一個地方。(此時就是存到字串TW中的某個地方)
存在物件(Object)內部是為了方便在之後的操作中可以快速訪問該hash值,而不需要每次都重新計算。
當然,物件的值發生改變時,會自動引用該物件的hashCode方法以重新產生新的hash值。
- HashMap 內部維護著一個儲存桶組(bucket array)。根據剛剛Key值產生的hash值,HashMap會將鍵值對(Key-Value)儲存到對應的儲存桶(bucket)中。
儲存桶組是一個array,每個儲存桶(bucket)可以儲存一個或以上的鍵值對(鏈表或紅黑樹)。
儲存桶組的目的是為了幫助HashMap高校地儲存與查找鍵值對。
hash值用於確定儲存位置(哪一個bucket),而bucket的索引用於實際儲存和檢索鍵值對。
儲存桶組的索引(是array,所以有索引) 是根據物件的hash值再計算得出的。
- 如果該bucket中已經有其他鍵值對存在,這就是發生了hash衝突。則新來的鍵值對會被添加在鏈表或紅黑樹的最末端。
注意
- 有重寫equals方法的話,hashCode方法也一定要重寫。反過來則非必須。
- 如果兩個物件的equals方法結果為相等,則它們的hashCode方法結果也必須相同。反過來說,hashCode方法的返回結果相同,equals的結果不一定相同,因為可能是hash衝突。
最後,反正開發工具都能自動產生equals() & hashCode()