equals() & hashCode() in Java

Joe Tsai
Joe Blog
Published in
4 min readJul 25, 2017

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原則

  1. 只要equals()中所用到的變數沒有被修改,hashCode必須產生相同的結果
  2. 如果兩個物件的equlas()比較結果是相等的,兩個物件的hashCode()必須產生相同的整數結果
  3. 兩個物件的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內建的自動產生功能!

--

--