2013-04-17 147 views
25

我有兩個從同一個類實例化的java對象。如何比較兩個java對象

MyClass myClass1 = new MyClass(); 
MyClass myClass2 = new MyClass(); 

如果我同時設置其屬性的完全相同的值,然後驗證它們是相同的

if(myClass1 == myClass2){ 
    // objects match 
    ... 

} 

if(myClass1.equals(myClass2)){ 
    // objects match 
    ... 

} 

然而,這些方法都不返回真值。我已經檢查過每一個的屬性,他們匹配。

如何比較這兩個對象以驗證它們是否相同?

+0

我做了谷歌,但我發現所有的例子從來沒有解釋,你不得不重寫equals方法。 –

+0

@AndroidAddict:那你爲什麼不問這個問題? – 2013-04-17 20:18:01

回答

71

您需要提供自己實現equals()MyClass

@Override 
public boolean equals(Object other) { 
    if (!(other instanceof MyClass)) { 
     return false; 
    } 

    MyClass that = (MyClass) other; 

    // Custom equality check here. 
    return this.field1.equals(that.field1) 
     && this.field2.equals(that.field2); 
} 

你也應該重寫hashCode()如果有在哈希表中正在使用你的對象的任何機會。一個reasonable implementation是將對象的字段的哈希碼的東西,如結合:

@Override 
public int hashCode() { 
    int hashCode = 1; 

    hashCode = hashCode * 37 + this.field1.hashCode(); 
    hashCode = hashCode * 37 + this.field2.hashCode(); 

    return hashCode; 
} 

上實現的哈希函數的詳細信息,請參閱this question

+1

爲什麼37?素數? – Aubin

+1

@Aubin通常情況下,素數在哈希代碼生成使用。如果我沒有記錯的話,它減少的機會,將有上生成散列碰撞。至於爲什麼要用37,我想這只是一個流行的選擇,我不知道有什麼特別的原因,使用37而不是說,13 – afsantos

+0

謝謝 - 一切真的。每個人都把我放在正確的道路上,但我只能接受一個正確的道路。 –

5

你必須正確地重寫方法equals()方法從Object類

編輯:我認爲,我的第一反應可能是誤解,因爲我不是太精確。所以我決定增加更多的解釋。

爲什麼你必須重寫equals()?那麼,因爲這是一個開發人員決定兩個對象是否相等意味着什麼的領域。大多數情況下參考平等是不夠的。

例如,假設您有一個HashMap,其鍵的類型爲Person。每個人都有姓名和地址。現在,你想使用鍵找到詳細的bean。問題是,您通常無法使用與地圖中相同的參考創建實例。你所做的是創建Person類的另一個實例。顯然,operator ==在這裏不起作用,你必須使用equals()。

但現在,我們來到另一個問題。假設您的收藏非常龐大,並且您想要執行搜索。天真的實現將使用equals()將您的關鍵對象與地圖中的每個實例進行比較。然而,這將是非常廣泛的。這裏是hashCode()。正如其他人所指出的,散列碼是一個不必是唯一的單個數字。重要的要求是每當equals()爲兩個對象賦予true時,hashCode()必須爲它們返回相同的值。反意義並不成立,這是一件好事,因爲散列碼將我們的鍵分成各種桶。我們在單個桶中有少量的Person類實例。當我們執行搜索時,該算法可以立即跳轉到正確的存儲桶,並且現在只對每個實例執行等於。因此,hashCode()的實現必須儘可能均勻地在桶中分配對象。

還有一點。一些集合需要在用作關鍵字的類中正確實現hashCode()方法,這不僅是出於性能原因。這些示例是:HashSet和LinkedHashSet。如果它們不覆蓋hashCode(),那麼默認的對象 hashCode()方法將允許將您可能認爲「有意義的 等於」的多個對象添加到「不允許重複」集合中。

一些使用的hashCode()

  • HashSet的藏品
  • LinkedHashSet
  • HashMap的

看一看Apache的公地這兩個類,可以讓你實現等於()和hashCode()容易

7

你需要重寫equalshashCode
equals將根據需要和hashCode是強制性爲了要在Collections正確使用和你的對象的屬性比較對象是否相等Maps

2

1)==評估基準平等在這種情況下
2)即時通訊不太清楚等於什麼,但爲什麼不簡單地重寫比較方法並將其植入MyClass?

5

你需要實現你的MyClass的equals()方法。

之所以==沒有工作,這是檢查它們指的是同一個實例。既然你爲每個做了new,每一個都是不同的實例。

之所以equals()沒有工作是因爲你沒有自己實現它。我相信它的默認行爲與==是一樣的。

請注意,如果您要實施equals(),則應該執行hashcode(),因爲很多java.util集合都期望這樣做。

+0

找到很好的解釋。簡明扼要。 – tommyO