Préface
Comme nous le savons tous, java.lang.object a un HashCode () et une méthode equals (), qui jouent un rôle important dans la conception de logiciels. Réécrivez ces deux méthodes dans certaines classes pour accomplir certaines fonctions importantes.
1. Pourquoi utiliser HashCode ()?
Les éléments de l'ensemble des ensembles sont désordonnés et non répatables. Alors, quelle est la base pour juger si deux éléments sont répétés?
Certaines personnes disent: Object.equal() est bien sûr utilisé pour comparer si les objets sont égaux. Cependant, il y a un grand nombre d'objets dans l'ensemble, et le nombre de comparaisons d'éléments d'objet ajoutés à l'ensemble ensemble augmentera progressivement, réduisant considérablement l'efficacité du fonctionnement du programme. Java utilise un algorithme de hachage (également appelé algorithme de hachage) pour résoudre ce problème. L'objet (ou les données) est directement mappé à une adresse en fonction d'un algorithme spécifique, et l'efficacité d'accès de l'objet est considérablement améliorée.
De cette façon, lorsqu'un ensemble contenant un grand nombre d'éléments doit ajouter un élément (objet), appelez d'abord le HashCode () de cet élément, et vous pouvez positionner l'emplacement de stockage réel de cet élément à la fois. S'il n'y a pas d'élément à cette position, cela signifie que cet objet est stocké dans l'ensemble de collection pour la première fois et que l'objet est stocké directement à cette position; S'il y a un objet à cette position, appelez Equal () pour voir si les deux objets sont égaux. Si la même chose est vraie, jetez l'élément et n'existez pas. S'il n'est pas égal, hachage à d'autres adresses.
C'est également la raison pour laquelle lorsque l'ensemble set stockant les données de type d'objet, il est nécessaire non seulement de réécrire la méthode HashCode () de l'objet, mais également de réécrire la méthode equals ().
2. Comment utiliser HashCode ()?
La relation entre la valeur de retour de HashCode () et Equals ()
Voici un exemple. Dans le développement réel de logiciels, il est préférable de réécrire ces deux méthodes.
Employé de classe publique {int EmployeeId; Nom de chaîne; @Override public boolean equals (objet obj) {if (obj == this) return true; Employé EMP = (Employé) OBJ; if (employeeId.equals (emp.getEmployeeId ()) && name == emp.getName ()) return true; retourne false; } @Override public int hashcode () {int hash = 1; hash = hash * 17 + employeeId; hash = hash * 31 + name.hashcode (); Hash de retour; }}Les méthodes equals () et hashcode () sont utilisées pour comparer dans la même classe, en particulier lors du stockage du même objet de classe dans le conteneur tel que défini pour stocker des objets dans la même classe.
Ici, nous devons d'abord comprendre un problème:
Deux objets avec equals () égaux, hashcode () doit être égal et deux objets avec equals () pas égaux, ne peuvent pas prouver que leur hashcode () n'est pas égal. En d'autres termes, pour deux objets dont la méthode equals () n'est pas égale, HashCode () peut être égal.
Ici, HashCode est comme l'indice de chaque personnage dans le dictionnaire, et equals () est comme comparer différents mots sous le même personnage dans le dictionnaire. Tout comme dans le dictionnaire, à la recherche des deux mots "soi" et "spontané" sous le mot "soi" dans le dictionnaire, si equals () est utilisé pour déterminer l'égalité des mots requête, c'est le même mot. Par exemple, les deux mots comparés par equals () sont "auto", alors les valeurs obtenues par la méthode hashcode () doivent être égales à ce moment; Si la méthode equals () compare les mots "self" et "spontané", le résultat est que vous ne voulez pas attendre, mais ces deux mots appartiennent aux mots "soi" et donc lorsque vous recherchez des index, c'est-à-dire, HashCode () est le même. Si equals () compare les mots «self» et «ils», les résultats sont également différents, et les résultats obtenus par HashCode () sont également différents pour le moment.
Inversement: HashCode () est différent, et equals () peut être introduit; HashCode () est égal, égal () peut être égal ou peut ne pas être égal.
Dans la classe d'objets, la méthode HashCode () est une méthode locale, qui renvoie la valeur d'adresse de l'objet. La méthode equals () dans la classe d'objets compare également les valeurs d'adresse des deux objets. Si equals () est égal, cela signifie que les valeurs d'adresse des deux objets sont également égales. Bien sûr, HashCode () est égal.
Étant donné que les égaux sont plus précis pour comparer les éléments égaux, pourquoi utiliser la méthode HashCode ()?
Parce que l'algorithme de hachage offre une grande efficacité dans la recherche d'éléments, si vous souhaitez savoir si une collection contient un objet, comment rédiger le code du programme approximatif?
Vous retirez généralement chaque élément un par un pour comparer avec l'objet que vous recherchez. Lorsque vous constatez que le résultat de la comparaison de méthode égaux entre un élément et l'objet que vous recherchez, arrêtez de rechercher et renvoyez des informations positives. Sinon, renvoyez des informations négatives. S'il y a de nombreux éléments dans une collection, tels que 10 000 éléments et ne contiennent pas l'objet que vous recherchez, cela signifie que votre programme doit retirer 10 000 éléments de la collection et comparer un par un pour obtenir une conclusion.
La classe d'objet définit une méthode HashCode () pour renvoyer le code de hash de chaque objet Java. Lorsque vous recherchez un objet de la collection HashSet, le système Java appelle d'abord la méthode HashCode () de l'objet pour obtenir la table de code de hash de l'objet, puis trouve la zone de stockage correspondante basée sur le hachage et obtient enfin chaque élément dans la zone de stockage et le compare à l'objet pour la méthode Equals. De cette façon, vous pouvez obtenir la conclusion sans traverser tous les éléments de la collection. On peut voir que la collection Hashset a de bonnes performances de récupération d'objets.
Cependant, l'efficacité du stockage d'objets dans la collection HashSet est relativement faible, car lors de l'ajout d'un objet à la collection HashSet, le code de hachage de l'objet doit être calculé en premier et l'emplacement de stockage de l'objet dans la collection est déterminé sur la base de ce code de hachage. Afin de s'assurer que les objets d'instance d'une classe peuvent être stockés normalement dans HashSet, les résultats des deux objets d'instance de cette classe doivent être égaux par rapport à la méthode equals () sont égaux; Autrement dit, si le résultat de obj1.equals(obj2) est vrai, le résultat de l'expression suivante doit également être true:obj1.hashCode() == obj2.hashCode() .
En d'autres termes: lorsque nous réécrivons la méthode égale d'un objet, nous devons réécrire sa méthode HashCode. Si nous ne réécrivons pas sa méthode HashCode, la méthode HashCode dans l'objet objet renvoie toujours l'adresse de hash d'un objet, et cette adresse n'est jamais égale. Ainsi, même si la méthode équivalente est réécrite pour le moment, il n'y aura pas d'effet spécifique, car si la méthode HashCode ne veut pas attendre, elle n'appellera pas la méthode égale de comparaison, donc elle n'a pas de sens.
La plupart des structures de données utilisent la méthode Equals pour déterminer si elles contiennent un élément, par exemple:
List <string> list = arrays.aslist ("a", "b", "c"); booléen contient = list.Contains ("b"); Cette variable contient le résultat est vrai car, bien que "b" soit des instances différentes (en outre, la résidence de chaîne est ignorée), ils sont égaux.
Ils utilisent un moyen rapide de comparer (réduire l'égalité de l'instance potentielle) au lieu de comparer chaque élément contenu dans l'instance. Une comparaison rapide nécessite uniquement de comparer les aspects suivants:
La comparaison du raccourci signifie qu'en comparant les valeurs de hachage, il peut remplacer une instance par une valeur entière. Les instances avec le même code de hachage ne sont pas nécessairement égales, mais les instances avec l'égalité doivent avoir la même valeur de hachage. (Ou devrait avoir, nous en discuterons bientôt) Ces structures de données sont souvent nommées par cette technique, et elles peuvent être identifiées par le hachage, parmi lesquels HashMap est le représentant le plus célèbre.
Ils fonctionnent généralement comme ceci:
Lors de l'ajout d'un élément, son code de hachage est utilisé pour calculer l'index du réseau interne (c'est-à-dire le soi-disant seau)
Si oui, les éléments inégaux ont le même code de hachage, ils se retrouvent sur le même seau et regroupés ensemble, par exemple en ajoutant à la liste.
Lorsqu'une instance fonctionne contient des opérations, son code de hachage sera utilisé pour calculer la valeur du seau (valeur d'index), et l'instance ne sera comparée que lorsque les éléments existent sur la valeur d'index correspondante.
Par conséquent, égal, HashCode est défini dans la classe d'objets.
Si HashCode est utilisé comme un raccourci pour déterminer l'égalité, alors il n'y a qu'une seule chose dont nous devons nous soucier: les objets égaux devraient avoir le même code de hash, c'est pourquoi si nous dépassons la méthode égaux, nous devons créer une implémentation de code de hashcode qui correspond!
Sinon, les objets égaux peuvent ne pas avoir le même code de hachage, car ils appellent l'implémentation par défaut des objets.
Citation des documents officiels
Convention générale de HashCode:
Lorsque vous appelez le même objet en cours d'exécution dans une application Java, la méthode HashCode doit toujours renvoyer le même entier. Cet entier n'a pas besoin d'être cohérent sur différentes applications Java. Selon equals(Object) , si deux objets sont égaux, les deux objets appellent la méthode HashCode doit produire le même résultat.
Selon equals(Object) , si les deux objets ne sont pas égaux, alors appeler la méthode HashCode ne produit pas nécessairement des résultats entiers différents. Cependant, les programmeurs devraient se rendre compte que la production de différents résultats entiers pour des objets inégaux améliorera probablement les performances de la table de hachage.
Implémentation de HashCode
Voici une simple implémentation de person.hashcode() :
@OverRidePublic int hashcode () {return objets.hash (FirstName, LastName);}La personne calcule le code de hachage en combinant plusieurs champs. Tous sont calculés par la fonction de hachage de l'objet.
Sélectionnez un champ
Mais quels champs sont liés? Les exigences nous aideront à répondre à cette question:
Si un objet égal doit avoir le même code de hachage, le code de hachage calculé ne doit pas inclure de champs qui ne sont pas utilisés pour les vérifications d'égalité. (Sinon, les deux objets sont simplement que ces champs sont différents, mais ils peuvent toujours être égaux, mais les codes de hachage des deux objets seront différents pour le moment.) Ainsi, le sous-ensemble des champs utilisés lorsque les champs de groupe de hachage doivent être égaux. Les mêmes champs sont utilisés par défaut, mais il y a quelques détails à considérer.
Résumer
Nous comprenons que le calcul du code de hachage consiste à compresser une valeur entière égale: les objets égaux doivent avoir le même code de hachage, et pour les considérations de performances, il est préférable de partager le même code de hachage que peu que possible d'objets inégaux.
Cela signifie que si la méthode équivalente est réécrite, la méthode HashCode doit être réécrite.
Lors de la mise en œuvre de HashCode, utilise les mêmes champs que celui utilisé dans Equals (ou un sous-ensemble de champs utilisés en égaux)
Il est préférable de ne pas inclure des champs mutables. N'envisagez pas d'appeler HashCode pour les collections. S'il n'y a pas de mode spécial spécifique spécifique, essayez d'utiliser un algorithme de hachage général.
D'accord, ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.