2010-02-23 16 views
6

Jak przesłonić metodę równości w klasie obiektów?Java override Object equals() metoda

tzn mam

class Person{ 

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

} 

chcę przekonwertować parametru obj do typu osoby, ale jeśli ja (osoba) obj to nie będzie działać.

+1

Uwaga trzeba uważać, jeśli masz non-końcową klasę. Zazwyczaj powinieneś sprawdzić klasę środowiska wykonawczego za pomocą 'obj.getClass() == Person' zamiast' instanceof Person'. Chociaż możliwe jest napisanie umowy, która sprawia, że ​​typy pochodne są równe (jak 'java.util.List'). Powinieneś także przesłonić 'hashCode' jeśli zastąpisz' equals', ale to prawdopodobnie trochę wyprzedza. –

Odpowiedz

8

Można rzucać go wewnątrz metody, wystarczy upewnić się, że jest odpowiedni rodzaj używając instancję

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

I myślałem o osobie otherPerson = (Person) obj; Dzięki – user69514

10

to faktycznie bardziej skomplikowana, niż mogłoby się wydawać. Czy Eclipse (lub jakikolwiek IDE, którego używasz) automatycznie generuje metodę: equals; zobaczysz, że zawiera kilka czeków i rzutów, zanim zrobi porównanie.

patrz także tutaj: 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

Wiele nie podoba mi się ten kod, ale jestem zmuszony do +1 dla '@ Override'. –

5

Spójrz na Regarding Object Comparison.

Należy pamiętać, że jeśli zastąpisz equals(), musisz także musi zastąpić hashCode(). Umowa equals/hashCode jest taka, że ​​jeśli dwa obiekty są równe, muszą mieć ten sam kod skrótu.

3

Jeśli planujesz utworzyć podklasy osoby, użyć czegoś podobnego

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

zamiast instanceof

+0

Dlaczego ktoś miałby używać getClass() zamiast instanceof? (Po prostu ciekawy.) – Tom

+2

np. jeśli Pracownik rozszerza Osobę; a Pracownik ma dodatkowe pola, takie jak id itp. Możesz uzyskać fałszywe pozytywne użycie osoby.equals (pracownika) – saugata

+1

To nie tyle fałszywe alarmy, o które musisz się martwić, ale ** naruszenie refleksyjności **. Bez względu na to, z czego korzystasz, możesz zasadniczo zagwarantować, że 'nowy pracownik(). Equals (new Person())' będzie fałszywy (osoba nie jest instancją pracownika). Wynik ** musi ** być taki sam, jeśli odwrócisz argumenty, więc Osoba ** nie może ** być równa podklasie samej sobie (chyba, że ​​zrobisz coś bardzo funky w metodzie podrzędnej "równy()"). –

2

Jedynym powodem używania getClass() zamiast instanceof jest, jeśli chcemy potwierdzić, że oba porównywane referencje wskazują obiekty tej samej klasy, a nie obiekty implementujące tę samą klasę bazową.

Say mamy Employeee i Managerm (wystaje Employee).

przyniesie wartość true, m.getClass() == Employee.class zwróci wartość false.

W niektórych przypadkach, ten ostatni może być korzystne, lecz rzadko w przypadku porównania przykładów, w equals() lub hashCode() metod.

0

Jeszcze jeden punkt może być dobry, aby wiedzieć, że po przesłonić equals() metody (a także hashcode()) metodę co możliwe, aby porównać dwa obiekty o tej samej klasy jak następuje:

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

wiem, że to zostanie odebrane, ale w moich podróżach znalazłem to najbardziej efektywny sposób, aby zastąpić porównanie obiektu, aby upewnić się, że dzieje się to samo globalnie:

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

lub jeśli nie jesteś compar ing ciągi:

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

wolę prostsze, null-bezpieczne (R) Objects.equals dla każdego typu pola:

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