En fait, d'après mes calculs, le facteur de charge "idéal" est plus proche de log 2 (~ 0.7). Bien que tout facteur de charge inférieur à cela donnera de meilleures performances. Je pense que .75 a probablement été sorti d'un chapeau.
Preuve :
Le chaînage peut être évité et la prédiction de branche exploitée en prédisant si un seau est vide ou non. Un seau est probablement vide si la probabilité qu'il soit vide dépasse .5.
Soit s la taille et n le nombre de clés ajoutées. En utilisant le théorème binomial, la probabilité qu'un seau soit vide est :
P(0) = C(n, 0) * (1/s)^0 * (1 - 1/s)^(n - 0)
Ainsi, un seau est probablement vide s'il y a moins de
log(2)/log(s/(s - 1)) clés
Comme s tend vers l'infini et si le nombre de clés ajoutées est tel que P(0) = .5, alors n/s approche rapidement log(2) :
lim (log(2)/log(s/(s - 1)))/s lorsque s -> l'infini = log(2) ~ 0.693...
0 votes
Java a de nombreuses distributions et versions différentes. Il s'agit d'une question très ancienne mais ceux qui visitent cet article peuvent utiliser des versions plus récentes de Java. Un point très important est qu'avant Java 8,
HashMap
n'est pas vraiment bien écrit. C'est pourquoi les développeurs de JDK ont réécritHashMap
en Java 8.0 votes
Si vous regardez le code source de
HashMap
dans Oracle JDK 7, vous pouvez voir que dans la méthodeaddEntry
(appelée parput(k, v)
), la méthoderesize
ne sera appelée que lorsque(size >= threshold) && (null != table[bucketIndex])
ce qui signifie que la taille doit atteindre le facteur de charge (c'est-à-dire75%
) de la capacité, ET, Le seau actuel a une collision. Par conséquent, le facteur de charge n'est qu'une partie de l'histoire dans Oracle JDK 7. Dans Oracle JDK 8, la condition précédente n'existe plus.