Pour le dire plus simple (autant que je pourrais plus simple) + quelques détails supplémentaires.
Ces propriétés dépendent de beaucoup de choses internes qu'il serait très cool de comprendre - avant de passer directement à elles.
TREEIFY_THRESHOLD -> lorsqu'un seul seau atteint cela (et que le nombre total dépasse MIN_TREEIFY_CAPACITY
), il se transforme en un nœud d'arbre rouge / noir parfaitement équilibré . Pourquoi? En raison de la vitesse de recherche. Pensez-y d'une manière différente:
il faudrait au plus 32 étapes pour rechercher une entrée dans un bucket / bin avec des entrées Integer.MAX_VALUE .
Quelques intro pour le sujet suivant. Pourquoi le nombre de bacs / seaux est-il toujours une puissance de deux ? Au moins deux raisons: plus rapide que le fonctionnement modulo et modulo sur les nombres négatifs sera négatif. Et vous ne pouvez pas placer une entrée dans un bucket "négatif":
int arrayIndex = hashCode % buckets; // will be negative
buckets[arrayIndex] = Entry; // obviously will fail
Au lieu de cela, il y a une belle astuce utilisée à la place de modulo:
(n - 1) & hash // n is the number of bins, hash - is the hash function of the key
C'est sémantiquement identique au fonctionnement modulo. Il conservera les bits inférieurs. Cela a une conséquence intéressante lorsque vous faites:
Map<String, String> map = new HashMap<>();
Dans le cas ci-dessus, la décision de l'emplacement d'une entrée est prise en fonction des 4 derniers bits uniquement de votre hashcode.
C'est là que la multiplication des seaux entre en jeu. Dans certaines conditions (cela prendrait beaucoup de temps à expliquer avec précision ), les seaux sont doublés de taille. Pourquoi? Lorsque la taille des godets est doublée, un autre élément entre en jeu .
Donc, vous avez 16 seaux - les 4 derniers bits du hashcode décident où va une entrée. Vous doublez les seaux: 32 seaux - 5 derniers bits décident de la destination de l'entrée.
En tant que tel, ce processus est appelé re-hachage. Cela pourrait devenir lent. C'est (pour les gens qui se soucient) que HashMap est "plaisanté" comme: rapide, rapide, rapide, lent . Il existe d'autres implémentations - recherche hashmap sans pause ...
Désormais, UNTREEIFY_THRESHOLD entre en jeu après un nouveau hachage. À ce stade, certaines entrées peuvent passer de ce bac à d'autres (elles ajoutent un bit de plus au (n-1)&hash
calcul - et en tant que tel peuvent se déplacer vers d' autres buckets) et cela peut atteindre cela UNTREEIFY_THRESHOLD
. À ce stade, il n'est pas rentable de conserver le bac sous forme de red-black tree node
, mais LinkedList
plutôt comme
entry.next.next....
MIN_TREEIFY_CAPACITY est le nombre minimum de compartiments avant qu'un certain compartiment ne soit transformé en arbre.
String
, ont un espace de valeur bien plus grand que leint
hashcode, par conséquent, les collisions sont inévitables. Maintenant, cela dépend des valeurs réelles, comme lesString
s réels , que vous mettez dans la carte, que vous obteniez une distribution uniforme ou non. Une mauvaise distribution peut être le résultat de la malchance.