equals( ) 跟 hashCode( )是兩個在Java中用來比較物件邏輯上是否相等的方法,透過重新定義eqauls( ),將比較的邏輯寫在物件的equals( )中,原本在調用端落落長的程式碼,從此Out!
何時需要override equals( )?
當你需要比較物件的邏輯相等(非物件一致性)時,且預設的equals( )無法滿足你的需求時,就需要override equals( )。
== 與 equals
==與equals( )都是用來比較在某條件上兩個物件是否相等,下面整理了一下兩者之間主要的差別。
- ==:比較物件(實體、記憶體空間)是否相同
- equals( ):比較物件的值(value)是否相同
- 預設的equals( ):功能如同==,用來比較兩個物件內存是否相等
- Value Class(Integer, String…)的equals( ):已被override用來比較值相等
override equals 需遵守的原則
- Reflexivity:x.eqauls(x) → true
- Symmetry:x.equlas(y) → true 則 y.eqauls(x) → true
- Transitivity:若 x.equals(y) → true、y.equals(z) → true,則 x.equals(z) → true
- Consistency:只要比較的對象不變,多次比較結果必相同
- Non-nullity:x.equlas(null) 必回傳 false
範例
這邊有個簡單的小範例,我想要比較兩個QRCode是不是相同,相同的條件為號碼及時間一樣,equals( )就派上用場了。
呼叫端只要執行下面的程式碼即可比對兩者是否相同:
別忘了override hashCode( )
在每個被override equals( )的Class中,也要記得override hashCode( ),否則違反了hashCode的原則,若有使用到HashMap、HashSet、HashTable,結果可能會不如預期,因為這些Class都使用到了hashCode。
HashCode原則
- 只要equals()中所用到的變數沒有被修改,hashCode必須產生相同的結果
- 如果兩個物件的equlas()比較結果是相等的,兩個物件的hashCode()必須產生相同的整數結果
- 兩個物件的equals()比較結果是不相等的,調用任一hashCode不一定要產生相同的整數結果,但是產生不同的整數結果,有助於提升hash table的效能。
IDE內建產生eqauls()及hashCode()功能
許多IDE都有提供這樣的功能,以Android Studio來說,在mac環境下按下ctrl+enter,會出現下面的懸浮視窗。
(1) 選擇equals() and hashCode()
(2) 直接點選Next
(3) 選擇要被寫入equals()裡面的變數
(4) 選擇要被寫入hashCode()裡面的變數
(5) IDE就會自動幫你產生以下程式碼了!
結論
碰到要判斷兩個物件邏輯上是否相等的時候,重新override equals()跟hashCode()是一個很好的方法,但是如果懶得自己override寫一堆判斷式,可以考慮直接使用IDE內建的自動產生功能!