equals() & hashCode() in Java

Joe Tsai
Joe Tsai
Jul 25, 2017 · 4 min read

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內建的自動產生功能!

Joe Blog

想到什麼寫什麼

Joe Tsai

Written by

Joe Blog

想到什麼寫什麼

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade