2011-12-01 67 views
12

我經常在不同的地方發現一個equals方法。它實際上做了什麼?我們必須在每個班級都有這個重要嗎?equals(Object obj)做什麼?

public boolean equals(Object obj) 
    { 
    if (obj == this) 
    { 
     return true; 
    } 
    if (obj == null) 
    { 
     return false; 
    } 
    if (obj instanceof Contact) 
    { 
     Contact other = (Contact)obj; 
     return other.getFirstName().equals(getFirstName()) && 
       other.getLastName().equals(getLastName()) && 
       other.getHomePhone().equals(getHomePhone()) && 
       other.getCellPhone().equals(getCellPhone()); 

    } 
    else 
    { 
     return false; 
    } 
} 
+4

我假設你已經看過了很清楚的文檔:http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html [向下滾動到equals()作爲直接鏈接似乎不適用於commments]。 – NPE

回答

31

它重新定義了對象的「平等」。

默認情況下(在java.lang.Object定義),一個目的是等於僅當它是同一個實例的另一個對象。但是當你覆蓋它時你可以提供自定義的相等邏輯。

例如,java.lang.String通過比較內部字符陣列限定平等。這就是爲什麼:

String a = new String("a"); //but don't use that in programs, use simply: = "a" 
String b = new String("a"); 
System.out.println(a == b); // false 
System.out.println(a.equals(b)); // true 

即使您可能不需要測試類似的平等,您使用的類。例如,List.contains(..)List.indexOf(..)的實現使用.equals(..)

檢查the javadocequals(..)方法所需的精確合同。

在許多情況下,當覆蓋equals(..)時,還必須覆蓋hashCode()(使用相同的字段)。這也是在javadoc中指定的。

1

它使你重新定義哪些對象相等並且不是,例如,你可以限定兩個Person對象作爲等於如果Person.ID是相同的,或者如果Weight等於取決於在應用程序中的邏輯。

看到這個:Overriding the java equals() method quirk

11

不同類別有不同的標準,是什麼讓兩個對象「相等」。通常情況下,equals()方法返回true,如果是相同的對象:

Object a = new Object(); 
Object b = new Object(); 
return(a.equals(b)); 

這將返回false沉綿他們都是「對象」類,它們是不一樣的實例。 a.equals(a)將返回true。

然而,就像一根繩索的情況下,你可以有2個不同的實例,但字符串平等是基於文本字符組成的字符串:

String a = new String("example"); 
String b = new String("example"); 
String c = new String("another"); 
a.equals(b); 
a.equals(c); 

這些都是不同的字符串的情況,但第一個等於將返回true,因爲它們都是「示例」,但第二個不會因爲「示例」不是「另一個」。

你不會需要重載equals()爲每類,只有當平等的特殊情況,如包含3串類,但只有第一個字符串是用於確定平等。在您發佈的例子,有可能是另一個領域,description這可能是2個不同的「聯繫人」不同,但2「聯繫人」會被認爲是相等的,如果這4個標準的比賽(第一/姓氏和家庭/手機數字),而匹配或不匹配的描述不會影響2個聯繫人是否相等。

3

equals方法被用來當一個人想知道,如果兩個物體是由什麼定義的對象找到合適的等價物。例如,對於String對象,等同性是關於兩個對象是否表示相同的字符串。因此,班級通常提供自己的實施方案,這種方式對於該班級來說是自然的。

equals方法與==的不同之處在於後者測試對象標識,即對象是否相同(不一定等同)。

8
從Bozho放棄一切

之外,還有一些額外的事情需要注意,如果重載等於:

  • 東西.equals(null)必須始終返回false - 即空不等於別的。如果您的代碼在第二秒鐘內處理此要求。

  • ,如果這是真的,東西 == 別的,然後還東西.equals(別的)也必須是真實的。 (即相同的對象必須相同)代碼的第一個如果處理此問題。

  • .equals應該是非空對象的對稱,即a.equals(b)應該與b.equals(a)相同。有時,如果您在父類和子類中進行子類化和重寫equals,則此要求會中斷。通常等於包含像if (!getClass().equals(other.getClass())) return false;這樣的代碼,至少可以確保不同的對象類型彼此不相等。

  • 如果您覆蓋equals您還必須覆蓋hashCode,以使下列表達式成立:if (a.equals(b)) assert a.hashCode() == b.hashCode()。即兩個彼此相等的對象的哈希碼必須相同。請注意,相反情況並非如此:具有相同散列碼的兩個對象可能彼此相等,也可能不相等。通常情況下,通過從用於確定對象的相等性的相同屬性派生hashCode來處理此要求。

在你的情況,hashCode方法可能是:

public int hashCode() { 
    return getFirstName().hashCode() + 
    getLastName().hashCode() + 
    getPhoneHome().hashCode() + 
    getCellPhone().hashCode(); 
} 
  • 如果實現Comparable兩個對象,如果它們是小相比,體積較大,或彼此相等,a.compareTo(b) == 0應當且僅當如果a.equalTo(b) == true

在許多IDE(例如Eclipse,IntelliJ IDEA,NetBeans)中,有一些特性g爲你提供equalshashCode,從而避免你繁瑣而且可能容易出錯的工作。

相關問題