1.Why 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? "Bien sûr, object.equal () est utilisé pour comparer si les objets sont égaux", a déclaré un certain singe. 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 de jeux 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 l'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.
2.Comment utiliser HashCode ()?
Le langage Java a cinq exigences qui doivent être suivies pour Equal () dans la conception des singes.
symétrie. Si A.equal (b) renvoie "vrai", alors B.equal (a) doit également retourner "vrai".
Réfléchissant. A. Equal (a) doit retourner "vrai".
Transitif. Si A.equal (b) retourne "vrai" et B.equal (c) renvoie "vrai", alors C.Equal (a) doit retourner "vrai".
cohérence. Si A.equal (b) revient "vrai", tant que le contenu de A et B reste inchangé, peu importe combien de fois a.equal (b) doit retourner "vrai".
Dans tous les cas, A. Equals (null) renvoie toujours "faux"; A. Equals (objets de différents types et a) Renvoie toujours "Faux".
La relation entre la valeur de retour de HashCode () et Equals ().
Si A.equals (b) renvoie "True", alors le HashCode () de A et B doit être égal.
Si A.equals (b) renvoie "false", alors le HashCode () de A et B peut être égal ou peut être inégal.
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; // D'autres méthodes seraient ici @Override public booléan 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; }}3. Ce qui suit est l'accent mis sur la méthode d'implémentation HashCode () des classes couramment utilisées.
hascode () de la classe de chaîne
public int hashcode () {int h = hash; if (h == 0) {int off = offset; char Val [] = valeur; int len = count; pour (int i = 0; i <len; i ++) {h = 31 * h + val [off ++]; } hash = h; } return h; }La chose la plus intéressante à propos de ce code est la méthode d'implémentation du hachage. La valeur de hachage finale calculée est:
S [0] 31n-1 + S [1] 31N-2 +… + S [N-1]
S [i] est le i-tème caractère d'une chaîne, et n est la longueur d'une chaîne. Alors pourquoi utiliser 31 ici au lieu d'autres chiffres?
31 est un nombre premier étrange. Si le multiplicateur est un nombre pair et que la multiplication déborde, les informations seront perdues car la multiplication avec 2 est équivalente au fonctionnement de décalage. Les avantages de l'utilisation de nombres premiers ne sont pas évidents, mais les résultats du hachage sont conventionnellement utilisés pour calculer les résultats du hachage. 31 a une bonne fonctionnalité, qui consiste à utiliser le décalage et la soustraction au lieu de la multiplication pour obtenir de meilleures performances: 31 * i == (i << 5) -I. Les machines virtuelles peuvent effectuer automatiquement cette optimisation. (De Java efficace)
Hascode () de la classe d'objets
HashCode () est une méthode native dans la classe d'objets. Comment appeler les méthodes natives?
public native int hashcode ();
La classe de méthode native de la classe d'objets peut être trouvée ici. Veuillez lire un autre blog pour une analyse approfondie
Méthodes statiques jninativemethod [] = {{"hashcode", "() i", (void *) & jvm_ihashcode}, {"wait", "(j) v", (void *) & jvm_monitorwait}, {"notify", "()", (void *) & jvm_monitory "() V", (void *) & jvm_monitornotifyall}, {"clone", "() ljava / lang / object;", (void *) & jvm_clone},};Le code source inclut getClass () (voir line58), etc. hashcode () (voir line43) est défini comme un pointeur vers JVM_IhashCode.
JVM.CPP définit la fonction JVM_IHASHCODE (ligne 504). Cette fonction appelle ObjectSynchronizer :: Fasthashcode, qui est déterminée dans synchronizer.cpp. Pour l'implémentation de FasthashCode dans la ligne 576 et Get_next_hash dans la ligne 530, vous pouvez vous référer à la mise en œuvre de Fasthashcode dans la ligne 576 et GET_NEXT_HASH dans la ligne 530.