Récemment, j'ai lu ce document Developer Works .
Le document est tout au sujet de définir hashCode()
et equals()
efficacement et correctement, mais je ne suis pas en mesure de comprendre pourquoi nous devons remplacer ces deux méthodes.
Comment prendre la décision de mettre en œuvre ces méthodes efficacement?
Réponses:
Joshua Bloch dit sur Java efficace
Essayons de le comprendre avec un exemple de ce qui se passerait si nous remplaçons
equals()
sans remplacerhashCode()
et essayons d'utiliser aMap
.Disons que nous avons une classe comme celle-ci et que deux objets de
MyClass
sont égaux si leurimportantField
est égal (avechashCode()
etequals()
généré par éclipse)Remplacer uniquement
equals
Si seulement
equals
est remplacé, alors lorsque vous appelez d'myMap.put(first,someValue)
abord, il hachera dans un compartiment et lorsque vous appellerez,myMap.put(second,someOtherValue)
il hachera dans un autre compartiment (car ils ont un autrehashCode
). Ainsi, bien qu'ils soient égaux, car ils ne hachent pas le même compartiment, la carte ne peut pas le réaliser et les deux restent dans la carte.Bien qu'il ne soit pas nécessaire de remplacer
equals()
si nous remplaçonshashCode()
, voyons ce qui se passerait dans ce cas particulier où nous savons que deux objets deMyClass
sont égaux si leurimportantField
est égal mais nous ne remplaçons pasequals()
.Remplacer uniquement
hashCode
Imaginez que vous avez ceci
Si vous ne remplacez que
hashCode
lorsque vous appelez,myMap.put(first,someValue)
il prend d'abord, calcule sonhashCode
et le stocke dans un compartiment donné. Ensuite, lorsque vous appelez,myMap.put(second,someOtherValue)
il doit remplacer d'abord par second selon la documentation de la carte car ils sont égaux (selon les besoins de l'entreprise).Mais le problème est que égal n'a pas été redéfini, donc lorsque la carte hache
second
et itère à travers le compartiment en recherchant s'il y a un objetk
tel qu'ilsecond.equals(k)
est vrai, il n'en trouvera pas commesecond.equals(first)
il le serafalse
.J'espère que c'était clair
la source
if you think you need to override one, then you need to override both of them
est faux. Vous devez remplacerhashCode
si votre classe remplaceequals
mais inverser n'est pas vrai.equals
violerait le contrat énoncé dans le javadoc deObject
: "Si deux objets sont égaux selon laequals(Object)
méthode, alors appeler lahashCode
méthode sur chacun des deux objets doit produire le même résultat entier."Bien sûr, toutes les parties de tous les contrats ne sont pas exercées dans tout le code, mais, officiellement, c'est une violation et je considère que c'est un bug qui attend.Les collections telles que
HashMap
etHashSet
utilisent une valeur de code de hachage d'un objet pour déterminer comment il doit être stocké dans une collection, et le code de hachage est à nouveau utilisé afin de localiser l'objet dans sa collection.La récupération de hachage est un processus en deux étapes:
hashCode()
)equals()
)Voici un petit exemple sur la raison pour laquelle nous devrions remplacer
equals()
ethashcode()
.Considérons une
Employee
classe qui a deux champs: l'âge et le nom.Créez maintenant une classe, insérez un
Employee
objet dans aHashSet
et testez si cet objet est présent ou non.Il imprimera les éléments suivants:
Désactivez maintenant
hashcode()
méthode, exécutez la même et le résultat serait:Maintenant, pouvez-vous voir pourquoi si deux objets sont considérés comme égaux, leur code de hachage doit également être égal? Sinon, vous ne seriez jamais en mesure de trouver l'objet puisque la méthode de hachage par défaut dans la classe Object propose pratiquement toujours un numéro unique pour chaque objet, même si la
equals()
méthode est remplacée de telle manière que deux ou plusieurs objets sont considérés comme égaux . Peu importe à quel point les objets sont égaux si leurs codes de hachage ne reflètent pas cela. Donc encore une fois: si deux objets sont égaux, leurs codes de hachage doivent également être égaux.la source
En définissant
equals()
et de manièrehashCode()
cohérente, vous pouvez améliorer la convivialité de vos classes en tant que clés dans les collections basées sur le hachage. Comme l'explique le document API pour hashCode: "Cette méthode est prise en charge au profit de tables de hachage telles que celles fournies parjava.util.Hashtable
."La meilleure réponse à votre question sur la façon d'implémenter ces méthodes efficacement est de vous suggérer de lire le chapitre 3 de Java efficace .
la source
hashCode()
.Autrement dit, la méthode equals dans Object vérifie l'égalité de référence, où deux instances de votre classe peuvent toujours être sémantiquement égales lorsque les propriétés sont égales. C'est par exemple important lorsque vous placez vos objets dans un conteneur qui utilise equals et hashcode, comme HashMap et Set . Disons que nous avons une classe comme:
Nous créons deux instances avec le même identifiant :
Sans égal égal, nous obtenons:
Correct? Eh bien peut-être, si c'est ce que vous voulez. Mais disons que nous voulons que les objets avec le même identifiant soient le même objet, qu'il s'agisse de deux instances différentes. Nous remplaçons les égaux (et le code de hachage):
Quant à l'implémentation d'equals et de hashcode, je peux recommander d'utiliser les méthodes d'assistance de Guava
la source
L'identité n'est pas l'égalité.
==
identité du test de l' .equals(Object obj)
la méthode compare le test d'égalité (c'est-à-dire que nous devons dire l'égalité en remplaçant la méthode)Nous devons d'abord comprendre l'utilisation de la méthode des égaux.
Afin d'identifier les différences entre deux objets, nous devons remplacer la méthode des égaux.
Par exemple:
Désormais, la méthode hashCode peut facilement comprendre.
hashCode produit un entier afin de stocker un objet dans des structures de données comme HashMap , HashSet .
Supposons que nous ayons la méthode override equals
Customer
comme ci-dessus,Tout en travaillant avec la structure de données lorsque nous stockons l'objet dans des compartiments (le compartiment est un nom de fantaisie pour dossier) Si nous utilisons la technique de hachage intégrée, pour plus de deux clients, cela génère deux codes de hachage différents. Nous stockons donc le même objet identique à deux endroits différents. Pour éviter ce genre de problèmes, nous devons remplacer la méthode hashCode également basée sur les principes suivants.
la source
Ok, permettez-moi d'expliquer le concept en termes très simples.
Premièrement, dans une perspective plus large, nous avons des collections, et hashmap est l'une des infrastructures de données dans les collections.
Pour comprendre pourquoi nous devons remplacer les deux méthodes égal et hashcode, si besoin de comprendre d'abord ce qu'est hashmap et ce qui fait.
Une table de hachage est une structure de données qui stocke des paires clé-valeur de données à la manière d'un tableau. Disons a [], où chaque élément de 'a' est une paire de valeurs clés.
De plus, chaque index du tableau ci-dessus peut être une liste liée ayant ainsi plus d'une valeur à un index.
Maintenant, pourquoi une table de hachage est-elle utilisée? Si nous devons rechercher parmi un grand tableau, puis en les recherchant si elles ne seront pas efficaces, alors quelle technique de hachage nous dit qui permet de pré-traiter le tableau avec une logique et de regrouper les éléments en fonction de cette logique, c'est-à-dire le hachage
par exemple: nous avons le tableau 1,2,3,4,5,6,7,8,9,10,11 et nous appliquons une fonction de hachage mod 10 pour que 1,11 soit regroupé. Donc, si nous devions rechercher 11 dans le tableau précédent, nous devrions itérer le tableau complet, mais lorsque nous le groupons, nous limitons notre portée d'itération, améliorant ainsi la vitesse. Cette structure de données utilisée pour stocker toutes les informations ci-dessus peut être considérée comme un tableau 2D pour plus de simplicité
Maintenant, en dehors de la table de hachage ci-dessus, elle indique également qu'elle n'ajoutera aucun doublon. Et c'est la principale raison pour laquelle nous devons remplacer les égaux et le hashcode
Donc, quand on dit que cela explique le fonctionnement interne de hashmap, nous devons trouver quelles méthodes le hashmap a et comment suit-il les règles ci-dessus que j'ai expliquées ci-dessus
donc le hashmap a la méthode appelée as put (K, V), et selon hashmap il devrait suivre les règles ci-dessus pour distribuer efficacement le tableau et ne pas ajouter de doublons
donc ce qu'il fait, c'est qu'il va d'abord générer le code de hachage pour la clé donnée pour décider dans quel index la valeur doit entrer. si rien n'est présent à cet index, la nouvelle valeur sera ajoutée là-bas, si quelque chose est déjà là-bas alors la nouvelle valeur doit être ajoutée après la fin de la liste chaînée à cet index. mais n'oubliez pas qu'aucun doublon ne doit être ajouté selon le comportement souhaité de la table de hachage. disons donc que vous avez deux objets entiers aa = 11, bb = 11. comme chaque objet dérivé de la classe d'objets, l'implémentation par défaut pour comparer deux objets est qu'il compare la référence et non les valeurs à l'intérieur de l'objet. Donc, dans le cas ci-dessus, les deux, bien que sémantiquement égaux, échoueront au test d'égalité, et la possibilité que deux objets ayant le même code de hachage et les mêmes valeurs existent, créant ainsi des doublons. Si nous remplaçons alors nous pourrions éviter d'ajouter des doublons. Vous pouvez également vous référer àTravail de détail
la source
hashCode()
:Si vous ne remplacez que la méthode du code de hachage, rien ne se passera. Parce qu'il retourne toujours new
hashCode
pour chaque objet en tant que classe Object.equals()
:Si vous ne remplacez que la méthode égale, cela
a.equals(b)
est vrai, cela signifie que les élémentshashCode
a et b doivent être identiques mais ne doivent pas se produire. Parce que tu n'as pas remplacéhashCode
méthode.Remarque: la
hashCode()
méthode de la classe Object renvoie toujours newhashCode
pour chaque objet.Donc, lorsque vous devez utiliser votre objet dans la collection basée sur le hachage, vous devez remplacer les deux
equals()
ethashCode()
.la source
Java met une règle qui
Donc, si dans notre classe nous remplaçons,
equals()
nous devonshashcode()
également remplacer la méthode pour suivre cette règle. Les deux méthodesequals()
ethashcode()
sont utiliséesHashtable
, par exemple, pour stocker des valeurs sous forme de paires clé-valeur. Si nous remplaçons l'un et pas l'autre, il est possible que leHashtable
ne fonctionne pas comme nous le souhaitons, si nous utilisons un tel objet comme clé.la source
Parce que si vous ne les remplacez pas, vous utiliserez l'implantation par défaut dans Object.
Étant donné que l'égalité d'instance et les valeurs de hascode nécessitent généralement une connaissance de ce qui constitue un objet, elles devront généralement être redéfinies dans votre classe pour avoir une signification tangible.
la source
Afin d'utiliser nos propres objets de classe comme clés dans des collections comme HashMap, Hashtable etc., nous devons remplacer les deux méthodes (hashCode () et equals ()) en ayant une connaissance du fonctionnement interne de la collection. Sinon, cela conduit à de mauvais résultats auxquels on ne s'attend pas.
la source
Ajout à la réponse de @Lombo
Quand devrez-vous remplacer equals ()?
L'implémentation par défaut de equals () de Object est
ce qui signifie que deux objets ne seront considérés comme égaux que s'ils ont la même adresse mémoire, ce qui ne sera vrai que si vous comparez un objet avec lui-même.
Mais vous voudrez peut-être considérer deux objets comme identiques s'ils ont la même valeur pour une ou plusieurs de leurs propriétés (reportez-vous à l'exemple donné dans la réponse de @Lombo).
Vous allez donc passer outre
equals()
dans ces situations et vous donneriez vos propres conditions d'égalité.J'ai réussi à implémenter equals () et cela fonctionne très bien, alors pourquoi demandent-ils également de remplacer hashCode ()?
Eh bien. Tant que vous n'utilisez pas de collections basées sur "Hash" sur votre classe définie par l'utilisateur, c'est très bien. Mais dans le futur, vous voudrez peut-être utiliser
HashMap
ouHashSet
et si vous ne le faites pasoverride
et "implémentez correctement" hashCode () , cette collection basée sur Hash ne fonctionnera pas comme prévu.Remplacer uniquement égal (ajout à la réponse de @Lombo)
Tout d'abord, HashMap vérifie si le hashCode de
second
est le même quefirst
. Seulement si les valeurs sont les mêmes, il procédera à la vérification de l'égalité dans le même compartiment.Mais ici, le hashCode est différent pour ces 2 objets (car ils ont une adresse mémoire différente de l'implémentation par défaut). Par conséquent, il ne se souciera même pas de vérifier l'égalité.
Si vous avez un point d'arrêt dans votre méthode equals () remplacée, il n'interviendra pas s'ils ont des codes de hachage différents.
contains()
vérifiehashCode()
et seulement si elles sont identiques, elle appellera votreequals()
méthode.Pourquoi ne pouvons-nous pas faire en sorte que HashMap vérifie l'égalité dans tous les compartiments? Il n'est donc pas nécessaire pour moi de remplacer hashCode () !!
Ensuite, vous manquez l'intérêt des collections basées sur Hash. Considérer ce qui suit :
Voici les clés stockées sous forme de compartiments.
Dites, vous voulez savoir si la carte contient la clé 10. Voulez-vous rechercher tous les compartiments? ou Souhaitez-vous rechercher un seul compartiment?
Sur la base du hashCode, vous identifieriez que si 10 est présent, il doit être présent dans le Bucket 1. Ainsi, seul le Bucket 1 sera recherché !!
la source
hashCode()
pour déterminer le compartiment et utilise laequals()
méthode pour trouver si la valeur est déjà présente dans le compartiment. Sinon, il sera ajouté sinon il sera remplacé par la valeur actuellehashCode()
pour trouver l'entrée (compartiment) en premier etequals()
pour trouver la valeur dans Entrysi les deux sont remplacés,
Carte < A >
si égal n'est pas remplacé
Carte < A >
Si hashCode n'est pas remplacé
Carte < A >
Contrat égal HashCode
la source
Considérez la collecte de balles dans un seau tout en couleur noire. Votre travail consiste à colorer ces balles comme suit et à les utiliser pour le jeu approprié,
Pour le tennis - jaune, rouge. Pour le cricket - blanc
Maintenant, le seau a des boules en trois couleurs jaune, rouge et blanc. Et que maintenant vous avez fait la coloration Vous seul savez quelle couleur est pour quel jeu.
Coloration des boules - Hachage. Choisir la balle pour le jeu - Égale.
Si vous avez fait la coloration et que quelqu'un choisit la balle pour le cricket ou le tennis, ils ne se soucieront pas de la couleur !!!
la source
Je cherchais l'explication "Si vous ne remplacez que hashCode, lorsque vous l'appelez,
myMap.put(first,someValue)
il prend d'abord, calcule son hashCode et le stocke dans un compartiment donné. Ensuite, lorsque vous appelezmyMap.put(first,someOtherValue)
il doit remplacer d'abord par second selon la documentation de la carte car ils sont égaux (selon notre définition). " :Je pense que la 2ème fois quand nous ajoutons
myMap
alors ce devrait être le «deuxième» objet commemyMap.put(second,someOtherValue)
la source
1) L'erreur courante est illustrée dans l'exemple ci-dessous.
la voiture verte est introuvable
2. Problème provoqué par hashCode ()
Le problème est dû à la méthode non remplacée
hashCode()
. Le contrat entreequals()
ethashCode()
est:Si deux objets ont le même code de hachage, ils peuvent ou non être égaux.
la source
Il est utile lors de l'utilisation d' objets de valeur . Ce qui suit est un extrait du Portland Pattern Repository :
la source
Supposons que vous ayez la classe (A) qui agrège deux autres (B) (C) et que vous devez stocker des instances de (A) dans la table de hachage. L'implémentation par défaut permet uniquement de distinguer les instances, mais pas par (B) et (C). Donc, deux instances de A pourraient être égales, mais par défaut ne vous permettrait pas de les comparer de manière correcte.
la source
Les méthodes equals et hashcode sont définies dans la classe d'objets. Par défaut, si la méthode equals renvoie true, le système ira plus loin et vérifiera la valeur du code de hachage. Si le code de hachage des 2 objets est également le même, alors les objets seront considérés comme identiques. Donc, si vous remplacez uniquement la méthode égal, alors même si la méthode remplacée est égale à 2 objets égaux, le code de hachage défini par le système peut ne pas indiquer que les 2 objets sont égaux. Nous devons donc également remplacer le code de hachage.
la source
true
pourequals
ne seront pas considérées comme correspondant. D'un autre côté, si les collections se produisent, notez que les choses ne peuvent pas avoir le même code de hachage, elles ne remarqueront probablement pas qu'elles sont égales.Equals et méthodes Hashcode en Java
Ce sont des méthodes de la classe java.lang.Object qui est la super classe de toutes les classes (classes personnalisées également et autres définies dans l'API java).
La mise en oeuvre:
public boolean equals (Object obj)
Cette méthode vérifie simplement si deux références d'objet x et y font référence au même objet. c'est à dire qu'il vérifie si x == y.
Il est réflexif: pour toute valeur de référence x, x.equals (x) doit renvoyer true.
Il est symétrique: pour toutes les valeurs de référence x et y, x.equals (y) doit retourner vrai si et seulement si y.equals (x) retourne vrai.
Il est transitif: pour toutes les valeurs de référence x, y et z, si x.equals (y) retourne vrai et y.equals (z) retourne vrai, alors x.equals (z) doit retourner vrai.
Il est cohérent: pour toutes les valeurs de référence x et y, plusieurs invocations de x.equals (y) retournent systématiquement vrai ou retournent systématiquement faux, à condition qu'aucune information utilisée dans les comparaisons égales sur l'objet ne soit modifiée.
public int hashCode ()
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 forme d'entier et est prise en charge au profit des classes de collecte basées sur le hachage telles que Hashtable, HashMap, HashSet etc. Cette méthode doit être remplacée dans chaque classe qui remplace la méthode equals.
Le contrat général de hashCode est:
Chaque fois qu'elle est invoquée plusieurs fois sur le même objet lors de l'exécution d'une application Java, la méthode hashCode doit toujours renvoyer le même entier, à condition qu'aucune information utilisée dans des comparaisons égales sur l'objet ne soit modifiée.
Cet entier n'a pas besoin de rester cohérent d'une exécution d'une application à une autre exécution de la même application.
Si deux objets sont égaux selon la méthode equals (Object), l'appel de la méthode hashCode sur chacun des deux objets doit produire le même résultat entier.
Il n'est pas nécessaire que si deux objets sont inégaux selon la méthode equals (java.lang.Object), alors appeler la méthode hashCode sur chacun des deux objets doit produire des résultats entiers distincts. Cependant, le programmeur doit être conscient que la production de résultats entiers distincts pour des objets inégaux peut améliorer les performances des tables de hachage.
Ressources:
JavaRanch
Image
la source
Dans l'exemple ci-dessous, si vous commentez la substitution pour égal ou hashcode dans la classe Personne, ce code ne parviendra pas à rechercher la commande de Tom. L'utilisation de l'implémentation par défaut de hashcode peut entraîner des échecs dans les recherches de table de hachage.
Ce que j'ai ci-dessous est un code simplifié qui extrait l'ordre des personnes par personne. La personne est utilisée comme clé dans la table de hachage.
la source
La classe String et les classes wrapper ont une implémentation différente de
equals()
ethashCode()
méthodes différentes de la classe Object. La méthode equals () de la classe Object compare les références des objets, pas le contenu. La méthode hashCode () de la classe Object renvoie un code de hachage distinct pour chaque objet, que le contenu soit le même.Cela entraîne un problème lorsque vous utilisez la collection de cartes et que la clé est de type Persistant, de type StringBuffer / builder. Puisqu'ils ne remplacent pas equals () et hashCode () contrairement à la classe String, equals () retournera false lorsque vous comparez deux objets différents même si les deux ont le même contenu. Cela rendra le hashMap stockant les mêmes clés de contenu. Le stockage des mêmes clés de contenu signifie qu'il enfreint la règle de Map car Map n'autorise pas du tout les clés en double. Par conséquent, vous remplacez les méthodes equals () ainsi que hashCode () dans votre classe et fournissez l'implémentation (l'EDI peut générer ces méthodes) afin qu'elles fonctionnent de la même manière que String's equals () et hashCode () et empêchent les mêmes clés de contenu.
Vous devez remplacer la méthode hashCode () avec equals () car equals () fonctionne selon hashcode.
De plus, le remplacement de la méthode hashCode () avec equals () permet de conserver le contrat equals () - hashCode (): "Si deux objets sont égaux, ils doivent avoir le même code de hachage."
Quand avez-vous besoin d'écrire une implémentation personnalisée pour hashCode ()?
Comme nous le savons, le fonctionnement interne de HashMap est basé sur le principe du hachage. Il existe certains compartiments où les entrées sont stockées. Vous personnalisez l'implémentation de hashCode () en fonction de vos besoins afin que les mêmes objets de catégorie puissent être stockés dans le même index. lorsque vous stockez les valeurs dans la collection Map à l'aide de la
put(k,v)
méthode, l'implémentation interne de put () est:Cela signifie qu'il génère un index et que l'index est généré en fonction du code de hachage d'un objet clé particulier. Donc, faites en sorte que cette méthode génère un code de hachage selon vos besoins, car les mêmes ensembles d'entrées de code de hachage seront stockés dans le même compartiment ou index.
C'est ça!
la source
hashCode()
est utilisée pour obtenir un entier unique pour un objet donné. Cet entier est utilisé pour déterminer l'emplacement du compartiment, lorsque cet objet doit être stocké dans certainsHashTable
,HashMap
comme la structure de données. Par défaut, lahashCode()
méthode Object renvoie et une représentation entière de l'adresse mémoire où l'objet est stocké.La
hashCode()
méthode des objets est utilisée lorsque nous les insérons dans unHashTable
,HashMap
ouHashSet
. Plus d'informationsHashTables
sur Wikipedia.org pour référence.Pour insérer une entrée dans la structure des données cartographiques, nous avons besoin à la fois de la clé et de la valeur. Si la clé et les valeurs sont des types de données définis par l'utilisateur,
hashCode()
la clé déterminera où stocker l'objet en interne. Lorsque vous devez également rechercher l'objet à partir de la carte, le code de hachage de la clé déterminera où rechercher l'objet.Le code de hachage pointe uniquement vers une certaine "zone" (ou liste, compartiment, etc.) en interne. Étant donné que différents objets clés pourraient potentiellement avoir le même code de hachage, le code de hachage lui-même ne garantit pas que la bonne clé est trouvée. Le
HashTable
itère alors cette zone (toutes les clés avec le même code de hachage) et utilise la clé deequals()
la méthode pour trouver la bonne clé. Une fois la bonne clé trouvée, l'objet stocké pour cette clé est renvoyé.Ainsi, comme nous pouvons le voir, une combinaison des méthodes
hashCode()
etequals()
est utilisée lors du stockage et de la recherche d'objets dans aHashTable
.REMARQUES:
Utilisez toujours les mêmes attributs d'un objet pour générer
hashCode()
et lesequals()
deux. Comme dans notre cas, nous avons utilisé l'ID d'employé.equals()
doit être cohérent (si les objets ne sont pas modifiés, il doit continuer à renvoyer la même valeur).Chaque fois
a.equals(b)
, alorsa.hashCode()
doit être le même queb.hashCode()
.Si vous remplacez l'un, vous devez remplacer l'autre.
http://parameshk.blogspot.in/2014/10/examples-of-comparable-comporator.html
la source
hashCode()
n'est pas utilisé pour renvoyer un entier unique pour chaque objet. C'est impossible. Vous l'avez contredit vous-même dans la deuxième phrase du quatrième paragraphe.À mon humble avis, c'est selon la règle - Si deux objets sont égaux, ils doivent avoir le même hachage, c'est-à-dire que des objets égaux doivent produire des valeurs de hachage égales.
Étant donné ci-dessus, égal à () par défaut dans Object est == qui fait une comparaison sur l'adresse, hashCode () renvoie l'adresse en entier (hachage sur l'adresse réelle) qui est à nouveau distinct pour Object distinct.
Si vous devez utiliser les objets personnalisés dans les collections basées sur Hash, vous devez remplacer à la fois equals () et hashCode (). Je peux finir par remplacer les deux objets employés différents, cela se produit lorsque j'utilise l'âge comme hashCode (), mais je devrais utiliser la valeur unique qui peut être l'ID employé.
la source
Pour vous aider à vérifier les objets en double, nous avons besoin d'un égal personnalisé et d'un hashCode.
Puisque le code de hachage renvoie toujours un nombre, il est toujours rapide de récupérer un objet en utilisant un nombre plutôt qu'une clé alphabétique. Comment ça va? Supposons que nous avons créé un nouvel objet en passant une valeur qui est déjà disponible dans un autre objet. Maintenant, le nouvel objet renverra la même valeur de hachage que celle d'un autre objet car la valeur transmise est la même. Une fois la même valeur de hachage renvoyée, la JVM ira à la même adresse mémoire à chaque fois et si, dans le cas où plusieurs objets sont présents pour la même valeur de hachage, elle utilisera la méthode equals () pour identifier l'objet correct.
la source
Lorsque vous souhaitez stocker et récupérer votre objet personnalisé en tant que clé dans Map, vous devez toujours remplacer equals et hashCode dans votre objet personnalisé. Par exemple:
Ici, p1 et p2 considéreront comme un seul objet et la
map
taille ne sera que de 1 car ils sont égaux.la source
Classe de test
Dans Object Class equals (Object obj) est utilisé pour comparer la comparaison d'adresses, c'est pourquoi lorsque dans la classe Test, si vous comparez deux objets, cela équivaut à la méthode donnant false, mais lorsque nous remplaçons hashcode (), il peut comparer le contenu et donner un résultat correct.
la source
Si vous remplacez
equals()
et nonhashcode()
, vous ne trouverez aucun problème à moins que vous ou quelqu'un d'autre n'utilisiez ce type de classe dans une collection hachée commeHashSet
. Les gens avant moi ont clairement expliqué la théorie documentée à plusieurs reprises, je suis juste ici pour fournir un exemple très simple.Considérons une classe dont le
equals()
besoin de signifier quelque chose de personnalisé: -Considérez maintenant cette classe principale: -
Cela produira la sortie suivante: -
Je suis content des résultats. Mais si je ne l'ai pas remplacé
hashCode()
, cela provoquera un cauchemar car les objetsRishav
avec le même contenu de membre ne seront plus traités comme uniques carhashCode
ils seront différents, comme généré par le comportement par défaut, voici la sortie: -la source
Les deux méthodes sont définies dans la classe Object. Et les deux sont dans sa mise en œuvre la plus simple. Donc, lorsque vous en avez besoin, vous souhaitez ajouter un peu plus d'implémentation à ces méthodes, vous devez remplacer dans votre classe.
Pour Ex: la méthode equals () dans l'objet vérifie uniquement son égalité sur la référence. Donc, si vous devez également comparer son état, vous pouvez le remplacer comme cela se fait dans la classe String.
la source
Bah - "Vous devez remplacer hashCode () dans chaque classe qui remplace equals ()."
[extrait de Effective Java, par Joshua Bloch?]
N'est-ce pas le contraire? Le remplacement de hashCode implique probablement que vous écrivez une classe de clé de hachage, mais le remplacement de equals ne le fait certainement pas. Il existe de nombreuses classes qui ne sont pas utilisées comme clés de hachage, mais qui souhaitent une méthode de test d'égalité logique pour une autre raison. Si vous choisissez «égal» pour cela, vous pouvez alors être mandaté pour écrire une implémentation de hashCode par application trop zélée de cette règle. Tout ce qui réussit est d'ajouter du code non testé dans la base de code, un mal qui attend de trébucher dans le futur. Également, écrire du code dont vous n'avez pas besoin est anti-agile. C'est juste faux (et une idée générée sera probablement incompatible avec vos égaux fabriqués à la main).
Ils auraient sûrement dû mandater une interface sur des objets écrits pour être utilisés comme clés? Quoi qu'il en soit, Object n'aurait jamais dû fournir par défaut hashCode () et equals () imho. Cela encourage probablement de nombreuses collections de hachage cassées.
Mais de toute façon, je pense que la "règle" est écrite à l'envers. En attendant, je continuerai à éviter d'utiliser "égal" pour les méthodes de test d'égalité :-(
la source