SitePoint Explore le monde Java: invitez les développeurs Java à contribuer
SitePoint continue d'étendre son champ de contenu et se concentrera sur Java dans un avenir proche. Si vous êtes un développeur Java expérimenté et que vous souhaitez contribuer à notre contenu Java, veuillez nous contacter pour partager les idées de sujet que vous souhaitez écrire.
Implémentation correcte des méthodes equals
et hashCode
dans Java
Vous avez implémenté la méthode equals
pour votre classe? super! Mais vous devez également implémenter la méthode . Comprenons pourquoi et comment l'implémenter correctement.
hashCode
Points clés:
Dans Java, les objets égaux devraient avoir le même code de hachage. Par conséquent, si la méthode
equals
Lors de la mise en œuvre de hashCode
, les mêmes champs utilisés dans la méthode hashCode
sont liés à l'optimisation des performances, vous ne devez donc pas consacrer trop d'efforts au hachage, à moins que l'analyse des performances n'indique des améliorations nécessaires. equals
equals
Bien que la méthode hashCode
soit raisonnable dans une perspective générale, la méthode
equals
La plupart des structures de données utilisent la méthode hashCode
pour vérifier si elles contiennent un élément. Par exemple:
equals
La variable
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
Cependant, la comparaison de chaque élément avec une instance transmise à la méthode contains
est inefficace, tandis qu'une classe de structures de données utilise une méthode plus efficace. Au lieu de comparer les instances demandées avec chaque élément qu'ils contiennent, ils utilisent des raccourcis pour réduire le nombre d'instances qui peuvent être égales, puis comparer uniquement les instances.
Ce raccourci est le code de hachage, qui peut être considéré comme l'égalité de l'objet à réduire à une valeur entière. Les instances avec le même code de hachage ne sont pas nécessairement égales, mais les instances égales ont le même code de hachage. (Ou devrait avoir le même code de hachage, dont nous discuterons plus tard.) Ces structures de données sont généralement nommées d'après leur nom technique, qui contient "hachage" dans lequel contains
est le représentant le plus célèbre.
Ils fonctionnent généralement comme suit: HashMap
contains
, le seau est calculé à l'aide de son code de hachage. Seuls les éléments qu'il contient sont comparés à l'instance. De cette manière, la mise en œuvre de la méthode contains
peut nécessiter que très peu, idéalement sans comparaison equals
.
Comme la méthode equals
, la méthode hashCode
est également définie dans la classe Object
.
penser au hachage
Si la méthode hashCode
est utilisée comme un raccourci pour déterminer l'égalité, alors il n'y a qu'une seule chose dont nous devrions vraiment nous soucier: les objets égaux devraient avoir le même code de hachage.
C'est aussi pourquoi si nous réécrivons la méthode equals
, nous devons créer une implémentation correspondante hashCode
! Sinon, les choses qui sont égales en fonction de notre implémentation peuvent ne pas avoir le même code de hachage, car ils utilisent l'implémentation de la classe Object
.
hashCode
Contrat de la méthode
Citer le code source:
hashCode
L'accord général de la méthode est:
- Chaque fois qu'il est appelé le même objet plusieurs fois lors de l'exécution d'une application Java, la méthode
hashCode
doit toujours renvoyer le même entier, à condition que les informations utilisées dans la comparaisonequals
de l'objet ne soient pas modifiées. Cet entier n'a pas besoin d'être cohérent entre l'exécution d'une application et l'autre exécution de la même application.- Si deux objets sont égaux selon la méthode
equals(Object)
, l'appel à la méthodehashCode
doit produire le même résultat entier sur chacun des deux objets.- Si les deux objets ne sont pas égaux selon la méthode
equals(Object)
, vous n'avez pas besoin d'appeler la méthodehashCode
sur les deux objets qui doivent produire des résultats entiers différents. Cependant, les programmeurs doivent se rendre compte que la génération de différents résultats entiers pour des objets inégaux peut améliorer les performances de la table de hachage.
Le premier point reflète l'attribut de cohérence de la méthode equals
, et le deuxième point est les exigences que nous avons dessinées ci-dessus. Le troisième point illustre un détail important dont nous discuterons plus tard.
implément hashCode
Méthode
Une implémentation très simple Person.hashCode
est la suivante:
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
Le code de hachage humain est calculé en calculant les codes de hachage des champs connexes et en les combinant ensemble. Les deux sont laissés à la fonction utilitaire Objects
pour le traitement. hash
Mais quels champs sont liés? Ces exigences aident à répondre à cette question: si un objet égal doit avoir le même code de hachage, le calcul du code de hachage ne doit contenir aucun champ qui n'est pas utilisé pour les vérifications d'égalité. (Sinon, seuls deux objets différents sur ces champs seront égaux, mais ont des codes de hachage différents.)
Par conséquent, l'ensemble des champs utilisés pour le hachage devrait être un sous-ensemble de l'ensemble des champs utilisés pour l'égalité. Par défaut, les deux utiliseront les mêmes champs, mais il y a quelques détails à considérer.
cohérence
Tout d'abord, il existe des exigences de cohérence. Il doit être interprété assez strictement. Bien qu'il permette au code de hachage de changer lorsque certains champs changent (ce qui est souvent inévitable pour les classes mutables), la structure de données de hachage n'est pas prête pour ce scénario.
Comme nous l'avons vu ci-dessus, le code de hachage est utilisé pour déterminer le seau de l'élément. Cependant, si les champs liés au hachage changent, le hachage n'est pas recalculé et le réseau interne n'est pas mis à jour.
Cela signifie que les requêtes ultérieures utilisant des objets égaux ou même en utilisant exactement la même instance échoueront! La structure de données calcule le code de hachage actuel (contrairement au code de hachage utilisé pour stocker les instances) et le recherche dans le mauvais seau.
Conclusion: il est préférable de ne pas utiliser de champs variables pour le calcul du code de hachage!
Performance
Le nombre de fois où le code de hachage est calculé peut être approximativement le même que le nombre de fois que la méthode est appelée. Cela est susceptible de se produire dans la partie de performance critique du code, il est donc logique de considérer les performances. Et contrairement à la méthode equals
, il y a plus de place pour l'optimisation ici. equals
Si les performances sont essentielles, l'utilisation de
peut également être le meilleur choix, car il nécessite de créer un tableau pour ses paramètres mutables. Objects.hash
conflit
Prenez tous vos efforts pour poursuivre les performances, alors qu'en est-il de cette implémentation?
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
Mais rappelez-vous ce que nous avions à propos des seaux avant? De cette façon, toutes les instances entreront le même seau! Cela se traduit généralement par une liste liée contenant tous les éléments, ce qui est très mauvais pour les performances. Par exemple, chaque
Call déclenche une analyse linéaire de la liste liée. contains
Par conséquent, nous voulons minimiser le nombre d'articles dans le même seau! Un algorithme qui renvoie un code de hachage qui est très différent même pour les objets très similaires est un bon début. Comment implémenter dépend en partie du champ sélectionné. Plus nous incluons dans le calcul, plus la possibilité que le code de hachage soit différente soit différente. Notez que c'est exactement l'opposé de ce que nous pensons de la performance. Donc, il est intéressant de noter que l'utilisation trop de ou trop peu de champs peuvent entraîner de mauvaises performances.
Une autre partie de la prévention des conflits est l'algorithme utilisé pour calculer réellement le hachage.Calculer la valeur de hachage
Le moyen le plus simple de calculer le code de hachage de champ est d'appeler la méthode
. Ils peuvent être combinés manuellement. Un algorithme commun consiste à commencer par un nombre arbitraire, puis à le multiplier à plusieurs reprises par un autre nombre (généralement un petit nombre premier), puis à ajouter le hachage du champ: hashCode
List<String> list = Arrays.asList("a", "b", "c"); boolean contains = list.contains("b");
Notez que même d'excellents algorithmes de hachage peuvent entraîner des conflits inhabituellement fréquents si les données d'entrée ont un modèle spécifique. À titre d'exemple simple, supposons que nous calculons la valeur de hachage d'un point en ajoutant les coordonnées x et y du point. Cela semble assez bon jusqu'à ce que nous réalisions que nous traitons souvent des points sur la ligne droite f (x) = -x, ce qui signifie que pour tous ces points, x y == 0. Conflit, beaucoup!
Mais encore une fois: utilisez des algorithmes communs et ne vous inquiétez pas à moins que l'analyse des performances ne montre des problèmes.
Résumé
Nous avons vu que le calcul des codes de hachage est comme la compression de l'égalité en valeurs entières: les objets égaux doivent avoir le même code de hachage, et pour des raisons de performance, il est préférable de partager la même chose que peu d'objets inégaux que possible que possible avec le même hachage code.
Cela signifie que si la méthode
est réécrite, la méthode equals
doit toujours être réécrite. hashCode
Méthode: hashCode
equals
hashCode
est liée aux performances, alors ne gaspillez pas trop d'énergie à moins que l'analyse des performances ne montre qu'elle est nécessaire. hashCode
Méthodes (FAQ) hashCode
hashCode()
en Java est une fonction intégrée qui renvoie une valeur entière. Il est principalement utilisé pour les collections basées sur le hachage (telles que hashCode()
, HashMap
et HashSet
) pour stocker et récupérer des objets plus efficacement. La méthode HashTable
fonctionne en conjonction avec la méthode hashCode()
pour s'assurer que chaque objet a un identifiant unique. Cela aide à récupérer rapidement les données, en particulier dans les grandes collections, améliorant ainsi les performances des applications Java. equals()
hashCode()
en Java? La méthode hashCode()
dans Java fonctionne en générant une valeur entière qui représente l'adresse mémoire de l'objet. Cette valeur est utilisée comme numéro d'index de l'objet dans une collection basée sur le hachage. Lorsque vous appelez la méthode hashCode()
sur l'objet, il utilise un algorithme de hachage pour générer cet entier unique. Cependant, il est important de noter que deux objets différents peuvent avoir le même hashCode
, qui est appelé conflit de hachage.
equals()
dans hashCode()
en java? et equals()
méthodes dans hashCode()
en Java est un ensemble de règles utilisées pour gérer leurs interactions. La convention indique que si deux objets sont égaux selon la méthode equals()
, l'appel à la méthode hashCode()
doit produire le même résultat entier sur chacun des deux objets. Cela garantit la cohérence et la précision lors du stockage et de la récupération d'objets dans une collection basée sur le hachage.
hashCode()
en Java? Réécrivez la méthode hashCode()
dans Java inclut la fourniture de votre propre implémentation qui renvoie un entier unique pour chaque objet. Cela peut être réalisé en utilisant des variables d'instance de l'objet et du multiplicateur privilégié. Les nombres premiers aident à distribuer uniformément les codes de hachage de l'ensemble, réduisant ainsi la possibilité de collisions de hachage.
signifie que la méthode hashCode()
génère le même entier pour deux objets différents. S'il n'est pas géré correctement, cela peut entraîner une perte de données. Pour éviter les conflits de hachage, vous pouvez améliorer l'algorithme de hachage pour générer des entiers plus uniques. De plus, l'utilisation de nombres premiers plus importants comme multiplicateurs peut aider à distribuer plus uniformément les codes de hachage de l'ensemble.
hashCode()
devrait-elle être réécrite? Réécrivez les méthodes hashCode()
peut améliorer les performances des applications Java, en particulier lorsqu'ils traitent de grandes collections. En fournissant votre propre implémentation, vous pouvez générer des codes de hachage plus uniques et uniformément distribués, réduisant la possibilité de conflits de hachage et garantissant une récupération des données plus rapide.
hashCode
? Oui, en Java, deux objets inégaux peuvent avoir le même hashCode
. C'est ce qu'on appelle le conflit de hachage. Cependant, en améliorant l'algorithme de hachage et en utilisant un plus grand nombre de premiers multiplicateurs, la possibilité que cela se produise peut être réduite.
hashCode()
? Si vous ne remplacez pas la méthode hashCode()
, Java utilisera son implémentation par défaut, qui peut ne pas fournir de code de hachage unique pour chaque objet. Cela peut entraîner des conflits de hachage et une récupération des données plus lente dans les collections basées sur le hachage.
hashCode()
Comment améliorer les performances des applications Java? hashCode()
améliore les performances d'une application Java en fournissant un identifiant unique pour chaque objet. Cela permet de récupérer les données plus rapidement dans les collections basées sur le hachage, car l'objet peut être trouvé directement en utilisant le code de hachage de l'objet sans rechercher toute la collection.
hashCode()
dans une collection non basée sur des hash? Bien que la méthode hashCode()
soit principalement utilisée pour les collections basées sur le hachage, elle peut également être utilisée pour les collections non basées sur Hash. Cependant, les avantages peuvent être moins évidents, car les collections non basées sur les Hash ne reposent pas sur le code de hachage pour le stockage et la récupération des données.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!