2008-08-19 3 views
19

J'ai toujours pensé que la méthode .equals() de java devrait être surchargée pour être rendue spécifique à la classe que vous avez créée. En d'autres termes, rechercher l'équivalence de deux instances différentes plutôt que deux références à la même instance. Cependant, j'ai rencontré d'autres programmeurs qui semblent penser que le comportement de l'objet par défaut devrait être laissé seul et une nouvelle méthode créée pour tester l'équivalence de deux objets de la même classe.Surcharger la méthode equals ou créer une nouvelle méthode

Quels sont les arguments pour et contre le remplacement de la méthode égale?

Répondre

19

Surcharger la méthode equals est nécessaire si vous voulez tester l'équivalence en Classes de bibliothèque standard (par exemple, s'assurer que java.util.Set contient des éléments uniques ou utiliser des objets comme clés dans les objets java.util.Map). Remarque: si vous remplacez les équivalents, assurez-vous d'honorer le contrat API comme décrit dans la documentation. Par exemple, assurez-vous également remplacer Object.hashCode:

Si deux objets sont égaux selon la méthode equals (Object), puis appeler la méthode hashCode sur chacun des les deux objets doivent produire le même résultat entier .

EDIT: Je n'ai pas posté cela comme une réponse complète sur le sujet, donc je vais l'écho des propos de Fredrik Kalseth que primordial égale fonctionne le mieux pour immutable objects. Pour citer l'API pour Map:

Note: grand soin doit être exercé si objets mutables sont utilisés comme clés de carte. Le comportement d'une carte n'est pas spécifié si la valeur d'un objet est modifiée d'une manière affectant les comparaisons alors que l'objet est une clé dans la carte.

+2

Le chapitre sur Java efficace (Josh Bloch, 1er éd.) Sur les méthodes java.lang.Object: http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf – McDowell

0

La méthode Equals est destinée à comparer des références. Il ne devrait donc pas être annulé pour changer son comportement.

Vous devez créer une nouvelle méthode pour tester l'équivalence dans les différents cas si vous avez besoin (ou utiliser la méthode CompareTo dans certaines classes .NET)

0

Vous devriez avoir besoin de remplacer la méthode equals() si vous voulez un comportement spécifique lors de l'ajout d'objets à des structures de données triées (SortedSet etc.)

Lorsque vous faites cela, vous devez également remplacer hashCode(). Pour une explication complète, voir here.

8

Je vous recommande fortement de prendre une copie de Java efficace et de lire l'article 7 en respectant le equals contract. Vous devez faire attention si vous remplacez les égaux pour les objets mutables, car la plupart des collections telles que Maps et Sets utilisent des équations pour déterminer l'équivalence, et la mutation d'un objet contenu dans une collection peut entraîner des résultats inattendus. Brian Goetz a également une très bonne overview of implementing equals and hashCode.

4

Vous ne devez jamais "redéfinir" & getHashCode pour les objets mutables - cela vaut aussi bien pour .net que pour Java. Si vous le faites, utilisez un objet comme la clé de f.ex un dictionnaire, puis changer cet objet, vous aurez des ennuis, car le dictionnaire s'appuie sur le code hash pour trouver l'objet.

Voici un bon article sur le sujet: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

0

Pour être honnête, en Java il n'y a pas vraiment un argument contre primordial est égal. Si vous avez besoin de comparer des instances pour l'égalité, alors c'est ce que vous faites.

Comme mentionné ci-dessus, vous devez être au courant du contrat avec hashCode et, de même, faites attention aux pièges autour de l'interface Comparable - dans presque toutes les situations que vous voulez que l'ordre naturel tel que défini par Comparable à être compatible avec égaux (voir le BigDecimal api doc pour l'exemple du compteur canonique)

Création d'une nouvelle méthode pour décider l'égalité, indépendamment de ne pas travailler avec les classes existantes de la bibliothèque, les mouches face à peu de convention Java.

2

Schlosnagle mentions mentionne @ David Josh Bloch Effective Java - doit lire c'est un pour tout développeur Java.

Il existe un problème connexe: pour les objets de valeur immuable, vous devez également envisager de remplacer compare_to. Le libellé standard pour si elles diffèrent est dans le Comparable API:

Il est généralement le cas, mais pas strictement nécessaire que (comparer (x, y) == 0) == (x.equals (y)) . De manière générale, tout comparateur qui viole cette condition devrait clairement indiquer ce fait. Le langage recommandé est "Note: ce comparateur impose des ordres qui sont incompatibles avec des égaux."

Questions connexes