2012-01-01 2 views
2

Quelles sont les conséquences du «pire cas» (scénarios du monde réel ici), si j'ai un objet (par exemple un haricot) qui a une méthode equals() pleine mais significative hashCode() méthode? Il semble que la plupart des API utilisent les méthodes equals() et compareTo() pour gérer les collections. Je me demande quand est le hashCode() le plus important?Equal object = Equal Hashcode Conséquences, java

+2

Dans une table de hachage? – helloworld922

+1

Ce message explique bien: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java – srchulo

Répondre

6

Les conséquences les plus défavorables sont que la table de hachage ne fonctionnera pas. Par exemple, permet de supposer que vous avez une classe simple comme ceci:

public class StringWrapper { 
    private String value; 
    ... 
    public boolean equals(Object other) { 
     // two objects are equal if their respective values are equal ... using `equals`. 
    } 
    // No hashcode override. 
} 

Ici, nous avons une classe que nous avons une classe n'obéit pas à l'un des invariants requis des Egaux/contrat de hashcode. Plus précisément, deux instances peuvent être égales, mais ont des hashcodes différents.

Lorsque vous ajoutez deux instances différentes de cette classe à un HashSet, vous pouvez finir avec les deux cas dans l'ensemble ... sur différentes chaînes de hachage. Vous obtenez des anomalies similaires lors de la suppression d'objets de l'ensemble, des tests pour voir si l'ensemble contient un objet, et ainsi de suite.

(Notez que vous pouvez avoir de la chance et que les deux instances finissent sur la même chaîne de hachage malgré des hashcodes différents.) Mais votre chance peut changer quand un autre objet indépendant est ajouté à la table de hachage. Redimensionner. Redimensionner est susceptible de provoquer des entrées avec différentes hashcodes à être redistribuées à différentes chaînes de hachage.)


Je me demande ... quand est le hashcode le plus important?

C'est toujours important.

Ou, pour le dire autrement, il est seulement sans importance si vous savez avec une certitude de 100% que les instances de la classe sont jamais utilisées dans les tables de hachage. (Et je ne sais pas comment vous pouvez savoir que, à moins que vous supprimez toutes les copies de la classe. Et qui rend toute la question sans objet!)


MISE À JOUR

@supercat mentionné le cas où vous ne pouvez pas écrire un hashcode décent.

S'il y a une bonne raison pour laquelle vous ne pouvez pas écrire une méthode hashcode() demi-décente, je préconiserais de l'ignorer pour lancer UnsupportedOperationException ou une autre. De cette façon, vous obtenez un échec rapide si quelqu'un essaie de mettre une instance dans une table de hachage ... plutôt qu'un trou noir de performance mystérieuse. (Je ne recommanderais pas retourner un hashcode constant.)

Il y a un scénario lié où vous pourriez faire ceci: lorsque l'objet est intrinsèquement mutable, et que vous voulez éviter le mauvais état qui se produit si vous muter une clé de hachage de sorte que son code de hachage change.

+0

Ou une recherche échoue avec une instance égale mais pas identique. –

+0

@DanielFischer - Je l'ai déjà mentionné. –

+0

N'a pas actualisé la page, vous avez modifié pendant que je lisais/tapais. –

1

Si vous vous intéressez à l'un ou l'autre de ces problèmes, vous devriez (vraiment) vraiment (vraiment) avoir besoin d'implémenter/de surcharger les deux. Voir Why do I need to override the equals and hashCode methods in Java? pour plus de détails, y compris ce qui peut arriver si ceux-ci ne sont pas implémentés avec des implémentations appropriées.

De plus, à partir another answer là:

Vous devez remplacer hashCode() dans toutes les classes qui l'emporte sur equals(). Si vous ne le faites pas, cela entraînera une violation du contrat général pour Object.hashCode(), ce qui empêchera votre classe de fonctionner correctement avec toutes les collections basées sur le hachage, y compris HashMap, HashSet et Hashtable.

de Effective Java, par Joshua Bloch

0

Cette méthode renvoie la valeur du code de hachage pour l'objet sur lequel cette méthode est invoquée. Cette méthode renvoie la valeur du code de hachage sous la forme d'un nombre entier et est prise en charge au profit des classes de hachage basées sur la hachage telles que Hashtable, HashMap, HashSet, etc. Cette méthode doit être surchargée dans chaque classe qui remplace la méthode equals.

reference

+0

s'il vous plaît donner raison de l'esprit downvote ???? –

+2

Je n'ai pas critiqué, mais votre réponse ne répond pas clairement à la question posée. Il veut savoir * pourquoi * vous devez remplacer la méthode et (plus précisément) ce qui se passe si vous ne le faites pas. –

+0

Je n'ai pas downvote non plus, mais .... cela ne répond pas à la question --- la question est? POURQUOI? le hashcode était important. – jayunit100

Questions connexes