Apprendre à améliorer Java: classes de conteneurs Commentaires (six) analyse de code source HashMap (de)

Précédent dans le contenu de base du HashMap fait une introduction détaillée, qui seront résolus et la méthode de vente pour HashMap sûrement nous avons aussi une meilleure compréhension de ce document, ce dans la perspective d'algorithmes pour analyser la HashMap ces fonctions.

HashCode

La première est que l'algorithme de HashCode HashMap sur, nous avons vu la méthode de vente de HashMap est la suivante:

 mettre publique V (touche K, la valeur V) { retour putVal (hachage (clé), clé, valeur, false, true); }

Ensuite, cette fonction de hachage, quel est-il? Jetons un coup d'oeil à ses vraies couleurs:

 / ** * Sera élevé et le calcul de la valeur de hachage calculée faible. Parce que l'utilisation de la puissance entière de 2 en tant que masque dans le hashmap, il ne se produit que sur le masque de bit de courant * Hachage change toujours conflit. (Dans l'exemple connu, un jeu de clés a tenu Float entiers consécutifs dans une petite table) Par conséquent, nous avons appliqué une opération de bits * Transfert vers le bas à fort impact. Ceci est considéré comme un compromis après la vitesse de fonctionnement, l'efficacité et la qualité. Parce que beaucoup ensemble de hash commune a une distribution raisonnable * (Vous ne pouvez pas bénéficier de la diffusion), et parce que nous utilisons l'arbre pour les cas de poignée où un grand nombre de collisions se produisent dans le bac, nous sommes donc au détriment des plus faibles moyens possibles * Certains XOR de déplacement pour réduire les pertes du système, et le plus important depuis peu la limite l'impact combiné de la capacité hashmap ne sera pas utilisé haché. * * Todo fonction perturbation * / static final int hachage (Object key) { int h; retour (clé == null) 0 :? (h = key.hashCode ()) ^ (h > > >  16); }

On peut voir ici est de ne pas utiliser simplement le hashCode une clé, mais plutôt sa haute et basse opération XOR 16 bits 16 bits fait une. ( ' > > > « Des moyens de décalage droit non signé, à savoir lorsqu'il est laissé section droite vide rempli de 0) qui est une fonction de la perturbation, l'effet sera décrit plus tard regard spécifiquement putval suivant les méthodes précédentes:

 1 final V putVal (hachage int, la clé K, la valeur de V, boolean onlyIfAbsent, 2 evict Boolean) { 3 Noeud < K, V > Tab; Noeud < K, V >  p; int n, i; 4 // Si ce tableau n'est pas initialisé, la première redimensionnées à la capacité initiale 5 if ((tab = tableau) == null || (n = tab.length) == 0) . 6 n = (tab = redimensionnement ()) de longueur; 7 // (n-1) et hachage ce lieu qui est basé sur hachage recherche numéro de série, hachage veulent apprendre le contenu plus connexes peuvent être consultés sous 8 if ((p = onglet ) == NULL) 9 // n'existe pas, créez un nouveau noeud 10 onglet  = Newnode (hachage, la clé, la valeur, null); 11 else { 12 Noeud < K, V >  e; K k; 13 // trouver d'abord le noeud correspondant 14 if (p.hash == hachage && 15 ((k = p.key) == || clé (clé! = NULL && key.equals (k)))) 16 e = p; 17 else if (p instanceof TreeNode) 18 // Si le nud de l'arbre, puis appelez la méthode appropriée putVal, placé troisième dans cette partie du contenu en 19 // todo putTreeVal 20 e = ((TreeNode < K, V > ) P) .putTreeVal (cet onglet, hachage, clé, valeur); 21 else { 22 // Si la liste est parcourue pour trouver entre 23 for (int binCount = 0 ;; ++ binCount) { 24 if ((e = p.next) == NULL) { 25 // si pas trouvé sur cette liste, puis créer un nouveau nud à la dernière pendaison 26 p.next = newNode (hachage, la clé, la valeur, null); 27 si (binCount > = TREEIFY_THRESHOLD - 1) // -1 pour le 1er Si la longueur de la chaîne atteint 28 // longueur maximale de l'arbre, l'arbre pour le contenu de cette fonction est placé troisième 29 // todo treeifyBin 30 treeifyBin (tab, hachage); 31 pause; 32} 33 if (e.hash == hachage && 34 ((k = e.key) == || clé (clé! = NULL && key.equals (k)))) 35 break; 36 p = e; 37} 38} 39 // Si le mappage de clé existe déjà, il sera remplacé par la valeur 40 si (e! = Null) {// mappage existant pour la clé 41 V = oldValue e.value; 42 if (! OnlyIfAbsent || oldValue == null) 43 e.value = valeur; 44 afterNodeAccess (e); 45 retour oldValue; 46} 47} 48 // ajouter un certain nombre de modifications 49 ++ modCount; 50 if (++ taille >  seuil) 51 redimensionnement (); 52 afterNodeInsertion (evict); 53 return null; 54}

Notez la huitième ligne de code:

patte

(N - 1) & hachage à-dire de prendre une clé d'index de tableau correspondant par la valeur de hachage de la taille de la table est pas effectuée opération modulo.

 , Pourquoi donc il? Tout d'abord, le but de la fonction de perturbation est d'étendre à fort impact, de sorte que la valeur calculée comprend 16 haut et caractéristiques 16 bits à la valeur de hachage encore plus insondable pour réduire la probabilité de collisions. Notes de la méthode de hachage, nous pouvons trouver la réponse, généralement hachage, ils sont en train de faire plus de processus de prise, mais la taille de la table HashMap est une puissance de 2, qui est certainement pas un nombre premier, puis prendre au fil du temps, la portée même de cartographie aura inévitablement la moitié, donc l'effet est évidemment bien pire, et, en fait, la division et le fonctionnement modulo est très lent, donc en JDK8, il utilise un moyen très intelligent pour hash. réglage de la taille de la table d'abord, la taille est devenue une puissance de 2, de sorte que l'utilisation de la taille-1 devient un masque, voici ce que je trouve une carte, puis bien expliquer le processus:

 n est la taille de la table, le défaut est 16, qui est binaire 10000, n - 1, par rapport à la correspondante 1111 binaire, alors il ne faut la valeur de hachage « et » opération, il devient un masque, sauf pour les quatre dernières sont toutes est réglé entre 0 et les quatre dernières gamme va certainement tomber (0 ~ n-1), exactement la gamme de taille du tableau, la beauté de la fonction de hachage est présente. A peine plus stable, une vague de féroce comme une opération de tigre.

 Ensuite, nous continuons sur une châtaigne, nous, étape par étape l'analyse, les valeurs de hachage cartographie des processus Xiao Ming et Li:

 Xiaoming valeur de hachage est 756692, est converti en un 10111000101111010100 binaire, la taille de la table est 32, n-1 = 31, correspondant au binaire: 11111, faire « et » après l'opération, le résultat est 10100, à savoir 20.

 Li valeur de hachage est 757012, est converti en un 10111000110100010100 binaire, et le résultat du calcul ne 11111, 10100 est obtenu, à savoir 20, donc il se heurta à Bob, mais veulent toujours à tour de rôle, puis accroché Li Xiao Ming de retour.

 Après avoir lu la fonction de hachage, nous allons examiner la fonction expansion.

Fonction d'extension

 En fait, avant que la fonction d'expansion a également été vu, dans la méthode ci-dessus putVal ans, de doubler à ce qui précède, la sixième ligne peut être vu la fonction de modification de taille qui est l'expansion de la fonction, regardons ses vraies couleurs:

 1 / ** 2 * initialiser la taille de la table ou pour l'expansion. Si la table est nul, répartis selon un seuil de capacité initiale du champ cible. 3 * Dans le cas contraire, puisque nous utilisons une puissance de 2 pour l'expansion, de sorte que dans la nouvelle table, chaque bac des éléments doit rester dans le même indice, ou se déplace à deux fois la puissance d'origine offset. 4 * / 5 Noeud finale < K, V > Resize () { 6 Noeud < K, V > ANCTAB table =; 7 oldCap int = (ANCTAB == null) 0 :? OldTab.length; 8 = int oldThr seuil; 9 int NEWCAP, newThr = 0; 10 if (oldCap >  0) { 11 if (oldCap > = MAXIMUM_CAPACITY) { 12 seuil = Integer.MAX_VALUE; 13 retour ANCTAB; 14} 15 // nouvelle capacité étendue à l'original deux fois 16 else if ((NewCap = oldCap < <  1) <  MAXIMUM_CAPACITY && 17 oldCap > = DEFAULT_INITIAL_CAPACITY) 18 // valeur de seuil est également ajusté à l'original deux fois 19 newThr = oldThr < <  1 // seuil double 20} 21 else if (oldThr >  0) // capacité initiale a été placé dans seuil 22 NEWCAP = oldThr; 23 else {// seuil initial signifie zéro en utilisant les valeurs par défaut 24 NEWCAP = DEFAULT_INITIAL_CAPACITY; 25 newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); 26} 27 si (newThr == 0) { 28 ft = flotteur (float) NewCap * loadfactor; 29 newThr = (NEWCAP <  MAXIMUM_CAPACITY && ft <  (Flotteur) MAXIMUM_CAPACITY? 30 ft (int): Integer.MAX_VALUE); 31} 32 seuil = newThr; 33 @SuppressWarnings ({ "rawtypes", "sans contrôle"}) 34 nud < K, V > Newtab = (Noeud < K, V > ) Nouveau noeud ; 35 TABLE = newtab; 36 // Le vieux nud de tableau rabâché dans un nouveau tableau 37 si (ANCTAB! = Null) { 38 for (int j = 0; j <  oldCap; ++ j) { 39 Noeud < K, V >  E; 40 if ((e = ANCTAB )! = Null) { 41 ANCTAB  = NULL; 42 if (e.next == null) 43 newtab  = E; 44 else if (e instanceof TreeNode) 45 ((TreeNode < K, V > ) E) .split (ce qui, newtab, j, oldCap); 46 else {// préserver l'ordre 47 Noeud < K, V >  loHead = null, loTail = null; 48 Noeud < K, V >  hiHead = null, hiTail = null; 49 Noeud < K, V >  suivant; 50 do { 51 next = e.next; 52 if ((e.hash & oldCap) == 0) { 53 if (loTail == null) 54 loHead = e; 55 autres 56 loTail.next = e; 57 loTail = e; 58} 59 else { 60 if (hiTail == null) 61 hiHead = e; 62 autres 63 hiTail.next = e; 64 hiTail = e; 65} 66} while ((E = suivante)! = Null); 67 si (loTail! = Null) { 68 loTail.next = null; 69 newtab  = LoHead; 70} 71 si (hiTail! = Null) { 72 hiTail.next = null; 73 newtab  = HiHead; 74} 75} 76} 77} 78} 79 retour newtab; 80}

Ici vous pouvez voir, si la table d'origine n'a pas été initialisé, puis, après avoir appelé la fonction sera étendue à la taille par défaut (16), également sur un déjà dit, HashMap est aussi une façon d'utiliser le chargement paresseux, et dans la construction fonction n'initialise pas la table, mais retardée jusqu'à ce que le premier élément d'insertion.

 Lors de l'utilisation d'insertion des éléments mis, si les bacs ont constaté que le niveau actuel d'occupation a dépassé la proportion de jeu de facteur de charge, puis se produit Redimensionner, est tout simplement la capacité initiale et les seuils sont ajustés à 2 fois l'original, après indice recalculé, le nud, puis dans le nouveau bac. Étant donné que la taille de la valeur d'index de la table calculée pour la matrice, de sorte qu'il existe une possibilité de réglage après l'expansion, la position de l'élément:

 La figure ci-dessus par exemple, si la valeur de hachage correspondante du cinquième bit est 0, puis faire après l'opération, le nombre résultant ne changera pas, il n'a pas position de changement, au contraire, si elle est 1, alors il est un nouveau numéro serait le nombre initial deviendra +16,.

 Eh bien, il ne semble pas beaucoup de, euh, sur la première partie de l'algorithme mis en place ici, après un HashMap venu parler de la entrySet, KeySet et les valeurs (si suffisamment de temps, puis parler aussi de la façon dont le iterator).

Belle maison | fille conte de deux villes
Précédent
Betty et une nouvelle église que nous aimons cette petite chose
Prochain
Alibaba pionnier de la scène Laboratoire d'intelligence artificielle pour ouvrir une nouvelle connectivité IdO d'entrée
java apprendre à améliorer vingt-deux: conteneurs détaillés (cinq) analyse de code source HashMap (sur)
Green Lake, chemin changera trois belles, 33 le long d'un lac Tong Tong une scène
Avril près de 40 corps à corps, beaucoup d'entre eux plaque rouge continue Yaohao « faible taux de réussite. »
Je vois ces filles l'amour, et c'est la beauté essentielle
Été, profitez de l'histoire de l'air frais, l'humanité comment petite la poursuite du bonheur
« Yao Ming » à l'Assemblée mondiale de tir de robot, la louange valeur Yen moins la technologie thermique
Créer des problèmes - après la moitié Shen Congwen | recrutement Xi'an
Les pirates informatiques et programmeurs Quelle est la différence? L'objectif du programmeur est de devenir une divinité, le but des pirates est de tuer Dieu!
Tragique et de sang! 73 ans plus tard, ces anciens bâtiments rester vigilants chaque Wuhan
Jimmy montres en plus d'apprendre l'accent sur la sécurité de la carte, mais aussi pour aider les enfants à apprendre
Que ce soit le Real Madrid ou au Portugal, le meilleur partenaire quand il est C Lo!