2010-02-23 5 views
6

Comment remplacer la méthode equals dans la classe d'objets?Substitution Java Méthode equals()

i.e. Je

class Person{ 

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

} 

Je veux convertir le paramètre obj à une personne de type, mais si je fais (personne) obj cela ne fonctionnera pas.

+1

Notez que vous devez être prudent si vous avez une classe non-finale. Typiquement, vous devriez vérifier la classe d'exécution avec 'obj.getClass() == Person' plutôt qu'avec' instanceof Person'. Bien qu'il soit possible d'écrire un contrat qui rend les types dérivés égaux (comme 'java.util.List'). En outre, vous devriez remplacer 'hashCode' si vous remplacez' equals', mais cela devance probablement un peu. –

Répondre

8

Vous pouvez le jeter dans la méthode, assurez-vous que est du bon type en utilisant instance de

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

Et j'ai pensé à Person otherPerson = (Person) obj; Merci – user69514

10

Il est en fait plus compliqué que vous pourriez penser. Avoir Eclipse (ou n'importe quel IDE que vous utilisez) générer automatiquement une méthode equals; vous verrez qu'il contient quelques vérifications et moulages avant de faire une comparaison.

Voir aussi ici: 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

Beaucoup de choses que je n'aime pas à propos de ce code, mais je suis forcé de +1 pour '@ Override'. –

5

Jetez un oeil à Regarding Object Comparison. Sachez que si vous remplacez equals()devez outrepasser hashCode(). Le contrat equals/hashCode est que si deux objets sont égaux, ils doivent avoir le même code de hachage.

3

Si vous envisagez de créer des sous-classes de personne, utilisez quelque chose comme

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

plutôt que instanceof

+0

Pourquoi utiliser getClass() au lieu de instanceof? (Juste curieux.) – Tom

+2

par exemple. si l'employé étend la personne; et Employé a des champs supplémentaires comme id etc. Vous pouvez obtenir un faux positif en utilisant person.equals (employé) – saugata

+1

Ce n'est pas tellement les faux positifs dont vous devez vous inquiéter, mais la ** violation de la réflexivité **. Indépendamment de ce que vous utilisez, vous pouvez garantir que 'new Employee(). Equals (new Person())' va être faux (Person n'est pas une instance de Employee). Le résultat ** doit ** être le même si vous inversez les arguments, donc une Personne ** ne peut pas ** être égale à une sous-classe de lui-même (sauf si vous faites quelque chose de très funky dans la méthode '' equals() 'de la sous-classe). –

2

La seule raison d'utiliser getClass() plutôt que instanceof est si l'on voulait affirmer que les deux références comparées pointent vers des objets de la même classe plutôt que des objets implémentant la même classe de base.

Disons que nous avons un Employeee et un Managerm (étend Employee).

m instanceof Employee donnerait vrai, m.getClass() == Employee.class retournerait faux.

Dans certains cas, ce dernier pourrait être préféré, mais rarement dans le cas de la comparaison des instances dans equals() ou hashCode() méthodes.

0

Un point peut être bon de savoir que lorsque vous remplacez la méthode equals() (et hashcode()) la méthode que vous pouvez comparer deux objets de même classe comme suit:

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

Je sais que cela répond, mais dans mes voyages, j'ai trouvé ce la façon la plus efficace de passer outre la comparaison d'un objet pour vous assurer qu'il arrive même dans le monde:

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

ou si vous n'êtes pas compar cordes: ing

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

Je préfère le plus simple, null-safe (r) Objects.equals pour tout type de terrain:

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