2010-02-23 4 views
6

Wie überschreibe ich die equals-Methode in der Objektklasse?Java überschreiben Objekt gleich() Methode

d.h Ich habe

class Person{ 

//need to override here 
public boolean equals (Object obj){ 

} 

ich den Parameter obj auf eine Art Person konvertieren wollen, aber wenn ich es tue (Person) obj es wird nicht funktionieren.

+1

Hinweis Sie müssen vorsichtig sein, wenn Sie eine nicht endgültige Klasse. Normalerweise sollten Sie die Laufzeitklasse mit 'obj.getClass() == Person 'und nicht mit' instanceof Person 'überprüfen. Es ist zwar möglich, einen Vertrag zu schreiben, der abgeleitete Typen gleich macht (wie 'java.util.List'). Außerdem sollten Sie 'hashCode' überschreiben, wenn Sie' equals' überschreiben, aber das geht wahrscheinlich etwas weiter. –

Antwort

8

Sie können es innerhalb der Methode werfen, nur sicherstellen, dass der richtige Typ ist Instanz von

if(obj instanceof Person) 
{ 
    Person otherPerson = (Person) obj; 
    //Rest of the code to check equality 
} 
else 
{ 
//return false maybe 
} 
+0

Und ich dachte über Person otherPerson = (Person) obj; Danke – user69514

10

mit Eigentlich ist es komplizierter, als Sie vielleicht denken. Haben Eclipse (oder welche IDE Sie verwenden) automatisch eine equals Methode generieren; Sie werden sehen, dass es einige Überprüfungen und Umwandlungen enthält, bevor es einen Vergleich durchführt.

Auch hier sehen: http://www.javapractices.com/topic/TopicAction.do?Id=17

8
@Override 
public boolean equals(Object o) 
{ 
    if (o instanceof Person) 
    { 
     Person c = (Person) o; 
     if (this.FIELD.equals(c.FIELD)) //whatever here 
     return true; 
    } 
    return false; 
} 
+3

Viele mag ich nicht über diesen Code, aber ich bin gezwungen, +1 für '@ Override'. –

5

einen Blick auf Regarding Object Comparison nehmen.

Achten Sie darauf, dass Sie equals() auch überschreiben müssen hashCode(). Der equals/hashCode-Vertrag besagt, dass, wenn zwei Objekte gleich sind, sie denselben Hash-Code haben müssen.

3

Wenn Sie Subklassen von Person zu erstellen, verwenden Sie so etwas wie

if (obj! = Null & & obj.getClass() == Person.class)

statt Instanceof

+0

Warum sollte man getClass() anstelle von instanceof verwenden? (Nur neugierig.) – Tom

+2

z.B. wenn Mitarbeiter Person ausdehnt; und Mitarbeiter hat zusätzliche Felder wie ID usw. Sie können ein falsch positives Ergebnis mit person.equals (Mitarbeiter) – saugata

+1

Es ist nicht so sehr die falsche positive müssen Sie sich sorgen, aber die ** Verletzung der Reflexivität **. Unabhängig davon, was Sie verwenden, können Sie grundsätzlich garantieren, dass "new Employee(). Equals (new Person())" falsch ist (Person ist keine Instanz von Employee). Das Ergebnis ** muss ** dasselbe sein, wenn Sie die Argumente invertieren, so dass eine Person ** nicht einer Unterklasse von sich gleich sein kann (es sei denn, Sie tun etwas sehr Funky in der Methode der Unterklasse ''equals()'). –

2

Der einzige Grund, getClass() anstelle von instanceof zu verwenden, ist, wenn man behaupten möchte, dass beide Referenzen, die verglichen werden, auf Objekte der exakt gleichen Klasse zeigen statt auf Objekte, die die gleiche Basisklasse implementieren.

Sagen wir eine Employeee und eine Managerm (erweitert Employee).

m instanceof Employee würde ergeben, m.getClass() == Employee.class würde false zurückgeben.

In einigen Fällen könnte letzteres bevorzugt werden, aber selten im Fall eines Vergleichs von Instanzen in equals() oder hashCode() Methoden.

0

Man kann mehr Punkt gut zu wissen, dass, nachdem Sie equals() Methode überschreiben (und auch hashcode()) Methode, die Sie zwei Objekte derselben Klasse vergleichen können wie folgt:

Person p1 = new Person(); 
Person p2 = new Person(); 

.... 

if (p1.equals(p2)) 

{ 
    // --- Two Persons are equal, w.r.t the fields you specified in equals method --- 

} 
0

das weiß ich beantwortet, aber in meinen Reisen habe ich diese den effizientesten Weg gefunden den Vergleich eines Objekts außer Kraft zu setzen, um sicherzustellen, dass es das gleiche geschieht global:

@Override 
public boolean equals(Object o) { 
    return o instanceof Person && this.getSomeMagicalField().equals(((Person) o).getSomeMagicalField()); 
} 

oder wenn Sie nicht compar sind ing Strings:

@Override 
public boolean equals(Object o) { 
    return o instanceof Person && this.getSomeMagicalField() == (Person) o).getSomeMagicalField(); 
} 
0

Ich ziehe den einfacheren, null-Safe (r) Objects.equals für jeden Feldtyp:

@Override 
public boolean equals(Object o) { 
    if (o instanceof Person) { 
     Person p = (Person) o; 
     return Objects.equals(p.FIELD, this.FIELD); 
    } 
    return false; 
} 
Verwandte Themen