Dans la méthode equals () de ma classe, j'utilise une variable HashMap d'instance privée pour comparer l'égalité. Cependant, 2 objets différents montrent toujours être égaux lors de la comparaison de leurs variables HashMap. De plus amples recherches m'ont amené au lien: Lien ici . Cependant, il dit simplement que la raison pour laquelle HashMap1.equals (HashMap2) ne fonctionne pas est parce que "apparemment les tableaux de Java ne peuvent pas être testés pour l'égalité sans écrire un code personnalisé."
Je n'ai pas compris cette raison. Quelqu'un peut-il me guider vers une raison détaillée?
La méthode equals
sur un type de tableau Java est équivalente à ==
, Car Java ne remplacent pas Object.equals
.
Si vous souhaitez comparer des tableaux "par valeur", vous devez soit utiliser la méthode Java.util.Arrays.equals(...)
appropriée, soit l'implémenter vous-même.
Si votre HashMap
utilise des tableaux comme clés ou valeurs, il va appeler la méthode equals
du tableau pour tester si les clés et/ou les valeurs sont les mêmes entre deux cartes. Cela ferait que HashMap.equals
Se comporterait étrangement (de votre point de vue). C'est ce que dit l'article lié. Cependant, la sémantique des tableaux niquement affecte l'égalité HashMap
si vous utilisez des tableaux comme classes de clés ou de valeurs. Si vous ne le faites pas, alors HashMap::equals
Devrait fonctionner comme prévu.
Les javadocs pour l'égalité sur les classes Map
sont un peu impliqués, mais ils se résument essentiellement à prendre les deux ensembles d'entrées, à comparer leurs tailles, puis à faire s1.containsAll(s2)
. Bien sûr, cela coûte cher, mais cela devrait fonctionner pour toutes les classes Map
qui implémentent correctement l'interface Map
.
Notez que l'utilisation de tableaux comme clés pour les cartes est une mauvaise idée pour plusieurs raisons:
equals
et hashCode
est incorrecte pour un HashMap
dans la plupart des scénarios. Pour la plupart des cas d'utilisation, vous avez besoin de la carte pour comparer les clés par valeur et non par identité d'objet.equals
/hashcode
, vous pourriez toujours casser les invariants d'une carte en modifiant une clé de tableau.L'article est juste. Les Hashmaps peuvent être comparés en toute sécurité à l'aide de la méthode equals () tant qu'il est possible de comparer les objets clés et les objets de valeur à l'aide de la même méthode. Dans l'article, les valeurs de mappage sont des tableaux, qui n'implémentent pas equals () comme prévu. À la place, ArrayList aurait résolu le problème.
Native Java n'ont pas de fonction .equals (). Donc, si les valeurs de votre table de hachage (ou les clés, je suppose) sont des tableaux, HashMap.equals () échouera. Je le soupçonne retomber sur Object.equals () qui vérifie simplement si les deux objets sont en fait le même objet.
// something like this
class Object {
public boolean equals( Object o) {
return this == o;
}
}
Vous pouvez contourner le problème en utilisant une variante sur un conteneur plutôt qu'un tableau [], car les conteneurs ont leur propre .equals () qui appelle equals () sur les éléments successifs des conteneurs plutôt que de simplement vérifier s'ils sont la même référence . Le code d'une implémentation Collection.equals peut ressembler à ceci:
public boolean equals(Object o) {
// sets never equal lists and visa versa
if (o instanceof MyCollectionSubclass) {
Iterator myIterator = iterator();
Iterator theirIterator = ((Collection)o).iterator();
while (myIterator.hasNext() && theirIterator.hasNext()) {
Object myObj = myIterator.next();
Object theirObj = theirIterator.next();
if (!myObj.equals(theirObj)) {
return false;
}
}
// at least one will be false or we wouldn't have left the above while loop
return myIterator.hasNext() == theirIterator.hasNext();
}
// not our class
return false;
}
Cela peut produire une comparaison de valeur réelle en fonction de ce que fait le contenu de la collection lorsque vous appelez leur equals()
.
L'égalité des tableaux de Java ne peut pas être testée sans écrire un code personnalisé
Ceci est juste une façon compliquée de dire que Java ne remplacent pas Object.equals()
. Par conséquent, si vous les comparez en utilisant equals()
(qui est ce que le equals
méthodes de toutes les classes de collection), vous obtenez "égalité d'instance", au lieu de "égalité de valeur".
C'est vraiment juste un cas particulier des différentes façons dont equals
fonctionne selon qu'il a été remplacé ou non.