2012-10-30 122 views
12

可能重複:
Overriding equals and hashCode in Java什麼時候需要重寫equals和hashcode方法?

如果我有

class A { 
    int x = 1; 
} 
... 
A a1 = new A(); 
A a2 = new A(); 
a1.equals(a2); 

如果我比較A的2個實例沒有覆蓋equals方法,我會得到預期的結果?

+0

這與處理,而不是HTTP的副本://計算器.com/questions/27581/overriding-equals-and-hashcode-in-java,因爲這是關於* how *來覆蓋'equals'和'hasCode',而這是關於*當*來覆蓋。 – Raedwald

+0

這似乎是一個更好的重複:http://stackoverflow.com/questions/13387742 –

回答

28

如果我比較2的A實例而不重寫equals方法,我會得到預期的結果嗎?

這取決於你所期望的:)

默認的實現會給你參考平等 - 換句話說,當你比較兩個引用,equals只會返回true,如果他們要引用同一個對象。

您通常會覆蓋equals以實現「值相等」 - 兩個不同的對象通常憑藉自身具有相同的字段值而被視爲相等。平等的確切含義將取決於您的設計 - 例如,兩個對象仍可通過其他方式進行區分。

如果覆蓋equals,你應該覆蓋hashCode是符合equals,例如,如果a.equals(b)是真的,那麼a.hashCode() == b.hashCode()。這將允許您的類的實例在基於散列的集合中用作鍵(例如HashMap),以便您可以根據等於的鍵查找基於原始值的值,而不必使用引用到確切的原始關鍵對象。

+8

所以這意味着,如果我不重寫equals方法,那麼equals()的行爲與==相同? – user926958

+8

@ user926958:是的,正好。 –

2

默認實現equals測試變量是否引用同一個對象。如果這不是你想要的,那麼你需要覆蓋equals。當您覆蓋equals時,通常需要覆蓋hashcode以使對象可用於散列表(或使用散列碼的其他數據結構)中。

3

如果我比較A的2個實例而不重寫equals方法,將 我得到預期的結果?

否。因爲您已經明確創建了兩個不同的實例。

爲什麼?的默認實現等於檢查兩個有關的對象是否指向java虛擬內存相同的內存位置

(這默認行爲java.lang.Object.equals()定義)什麼時候需要覆蓋equals和hashcode方法?

當程序員會覆蓋等於最常見的情況()和hashCode()是,如果你需要在java.util.Map實現使用有關類的實例作爲

  1. java.util.Set實現中的值
  2. 您想檢查同一類的兩個不同實例之間的值是否相等(在這種情況下重寫equals()是必需的,而hashcode()不是 - 但是這是一種很好的編程習慣)

equals和hashCode的一般合同是:

if a1.equals(a2) 
    it is mandatory that a1.hashcode() == a2.hashcode() 
if a1.hashcode() == a2.hashcode() 
    it is not mandatory that a1.equals(a2) 

我想這足夠的數據來一天:)

相關問題