web-dev-qa-db-fra.com

Comment comparer deux Java

J'ai deux Java qui sont instanciés à partir de la même classe.

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

Si je définis leurs deux propriétés avec exactement les mêmes valeurs et que je vérifie qu'elles sont identiques

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

}

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

}

Cependant, aucune de ces approches ne retourne une valeur réelle. J'ai vérifié les propriétés de chacun et ils correspondent.

Comment comparer ces deux objets pour vérifier qu'ils sont identiques?

29
Roy Hinkley

Vous devez fournir votre propre implémentation de equals() dans 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);
}

Vous devez également remplacer hashCode() s'il existe un risque que vos objets soient utilisés dans une table de hachage. Un implémentation raisonnable consisterait à combiner les codes de hachage des champs de l'objet avec quelque chose comme:

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

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

    return hashCode;
}

Voir cette question pour plus de détails sur l'implémentation d'une fonction de hachage.

79
John Kugelman

Vous devez remplacer equals et hashCode.
equals comparera les objets pour égalité en fonction des propriétés requises et hashCode est obligatoire pour que vos objets puissent être utilisés correctement dans Collections et Maps

7
Cratylus

Vous devez remplacer correctement la méthode equals () à partir de la classe Object

Edit : Je pense que ma première réponse a été mal comprise probablement parce que je n’étais pas trop précise. J'ai donc décidé d'ajouter plus d'explications.

Pourquoi devez-vous remplacer equals ()? Eh bien, parce qu’il appartient au développeur de décider de l’égalité entre deux objets. L’égalité de référence ne suffit pas dans la plupart des cas.

Par exemple, imaginons que vous ayez un HashMap dont les clés sont de type Person. Chaque personne a un nom et une adresse. Maintenant, vous voulez trouver un haricot détaillé en utilisant la clé. Le problème est que vous n'êtes généralement pas en mesure de créer une instance avec la même référence que celle de la carte. Ce que vous faites est de créer une autre instance de la classe Person. Il est clair que l'opérateur == ne fonctionnera pas ici et que vous devez utiliser equals ().

Mais maintenant, nous arrivons à un autre problème. Imaginons que votre collection soit très volumineuse et que vous souhaitiez effectuer une recherche. L'implémentation naïve comparerait votre objet clé avec chaque instance d'une carte en utilisant equals (). Ce serait toutefois très coûteux. Et voici le hashCode (). Comme d'autres l'ont souligné, le hashcode est un nombre unique qui ne doit pas nécessairement être unique. La condition importante est que chaque fois que equals () donne la valeur true pour deux objets, hashCode () doit renvoyer la même valeur pour les deux. L'implication inverse ne tient pas, ce qui est une bonne chose, car le hashcode sépare nos clés en sortes de compartiments. Nous avons un petit nombre d'instances de la classe Person dans un seul compartiment. Lorsque nous exécutons une recherche, l’algorithme peut passer immédiatement à un compartiment correct et exécuter à présent des actions équivalentes pour chaque instance. L'implémentation de hashCode () doit donc répartir les objets de la manière la plus uniforme possible dans les compartiments.

Il y a un autre point. Certaines collections nécessitent une implémentation appropriée d'une méthode hashCode () dans des classes utilisées comme clés, non seulement pour des raisons de performances. Les exemples sont: HashSet et LinkedHashSet. S'ils ne remplacent pas hashCode (), la méthode Object par défaut hashCode () autorisera l'ajout de plusieurs objets que vous pourriez considérer comme "équivalents" à votre ensemble "aucun doublon autorisé".

Certaines des collections qui utilisent hashCode ()

  • HashSet
  • LinkedHashSet
  • HashMap

Jetez un coup d’œil à ces deux classes d’Apache communes qui vous permettront d’implémenter facilement equals () et hashCode ()

5
rarry

Vous devez implémenter la méthode equals () dans votre MyClass.

La raison pour laquelle == N'a pas fonctionné est qu'elle vérifie qu'ils se réfèrent à la même instance. Puisque vous avez fait new pour chacun, chacun est une instance différente.

La raison pour laquelle equals() n'a pas fonctionné est que vous ne l'avez pas encore implémenté vous-même. Je crois que son comportement par défaut est la même chose que ==.

Notez que vous devez également implémenter hashcode() si vous souhaitez implémenter equals() car beaucoup de collections Java.util l'attendent.

5
Daniel Kaplan

1) == évalue l'égalité de référence dans ce cas
2) Je ne suis pas trop sûr de l'égalité, mais pourquoi ne pas simplement ignorer la méthode de comparaison et l'installer dans MyClass?

2
Infested