2010-05-07 11 views
2

J'ai la situation suivante: J'ai besoin de trier les arbres en fonction de la hauteur, donc j'ai rendu l'arbre comparable en utilisant l'attribut height. Cependant, on m'a aussi dit d'écraser les méthodes equals et hashCode pour éviter un comportement imprévisible.Java: Si je remplace la méthode .equals, puis-je toujours tester l'égalité de référence avec ==?

Encore, parfois je peux vouloir comparer les références des racines ou quelque chose le long de ces lignes en utilisant ==. Est-ce encore possible ou est-ce que la comparaison == appelle la méthode égale?

+0

s/écrasement/override/p –

Répondre

3

Oui, == n'appelle pas hashCode ou est égal à. Vous pouvez toujours tester l'égalité de référence comme ceci.

0

== n'appelle pas d'égal. Donc, il est toujours trouvé pour les contrôles d'identité.

Comme de nombreuses implémentations de equals départ avec this == other vérifier que vous obtiendrez un StackOverflow littérale si elle était appelait equals dans les coulisses.

0

== teste l'égalité référentielle. Cela n'appellera pas les égaux.

7

equals() est destiné à comparer un objet avec des règles définies par le programmeur. Dans votre exemple, vous comparez vos arbres en fonction de la hauteur, vous écrivez donc equals() afin de comparer les hauteurs.

==, comme vous l'avez dit, compare les références. Ceux-ci ne sont pas touchés par equals() ni par hashCode(). Donc vous ne changerez pas son comportement.

1

Le remplacement de la méthode equals() n'aura PAS d'effet sur l'opérateur ==. == est utilisé pour tester si 2 références pointent vers le même objet. La méthode equals() "significativement" compare 2 objets.

Il est important de réaliser ici l'implication du travail "significatif". L'égalité est plus facile à comprendre lorsque vous comparez, par exemple, 2 chaînes ou 2 entiers. C'est pourquoi, la méthode equals() héritée de la classe Object est déjà surchargée par les classes String et Wrapper (Integer, Float, etc.). Cependant, que faire si vous comparez 2 objets de type Song. Ici, l'égalité peut être établie sur la base de
1) Nom de l'artiste
2) Titre de la chanson
3) ou un autre critère

Par conséquent, vous devez remplacer la méthode equals() pour « explicitement » déterminer "quand" 2 objets Song sont considérés égaux. Le "comportement imprévisible" que vous avez mentionné dans votre question se rapporte à des objets comme celui ci-dessus (Song) se comportent lorsqu'il s'agit de collections comme Map. Vous NE DEVRIEZ PAS utiliser ces objets dans une carte tant que vous n'avez pas écrasé la méthode equals() et hashcode(). La raison en est que la recherche et l'indexation de hashmap fonctionnent. Reportez-vous à JavaDoc pour les règles spécifiques. Ce que vous devriez vous rappeler est:
Si 2 objets sont significativement égaux, leur code de hachage devrait renvoyer la même valeur. Cependant, il n'est pas nécessaire que 2 objets soient égaux, s'ils retournent le même code. Encore une fois, Java n'applique aucune règle à ce sujet. Il est de votre responsabilité d'implémenter les méthodes equals() et hashcode() correctement.

1

Je pense qu'une question plus importante ici est de savoir s'il est approprié de mettre en œuvre des comparables sur ces objets.Il peut être plus approprié d'utiliser un comparateur pour les opérations qui fonctionnent sur la hauteur, et non d'intégrer le calcul ordinale dans la classe elle-même.

Ma philosophie générale sur ceci est de mettre en œuvre seulement comparable s'il y a un ordre vraiment naturel pour l'objet. Dans le cas d'un nœud d'arbre, la hauteur est-elle seulement que tout le monde pourrait vouloir trier? Peut-être que c'est une classe privée, et la réponse est «oui». Mais même dans ce cas, créer un Comparateur n'est pas un travail supplémentaire, et cela laisse les choses flexibles au cas où vous décidiez de faire de ce nœud d'arbre une classe protégée ou publique un jour.