L'implémentation standard est faible et son utilisation entraîne des collisions inutiles. Imaginez un
class ListPair {
List<Integer> first;
List<Integer> second;
ListPair(List<Integer> first, List<Integer> second) {
this.first = first;
this.second = second;
}
public int hashCode() {
return Objects.hashCode(first, second);
}
...
}
Maintenant,
new ListPair(List.of(a), List.of(b, c))
et
new ListPair(List.of(b), List.of(a, c))
ont la même chose hashCode
, à savoir 31*(a+b) + c
que le multiplicateur utilisé pour List.hashCode
est réutilisé ici. De toute évidence, les collisions sont inévitables, mais produire des collisions inutiles est tout simplement ... inutile.
Il n'y a rien de vraiment intelligent à utiliser 31
. Le multiplicateur doit être impair afin d'éviter de perdre des informations (tout multiplicateur pair perd au moins le bit le plus significatif, des multiples de quatre en perdent deux, etc.). Tout multiplicateur impair est utilisable. Les petits multiplicateurs peuvent conduire à un calcul plus rapide (le JIT peut utiliser des décalages et des ajouts), mais étant donné que la multiplication a une latence de seulement trois cycles sur Intel / AMD moderne, cela n'a guère d'importance. Les petits multiplicateurs entraînent également plus de collision pour les petites entrées, ce qui peut parfois être un problème.
L'utilisation d'un nombre premier est inutile car les nombres premiers n'ont aucune signification dans l'anneau Z / (2 ** 32).
Donc, je recommanderais d'utiliser un grand nombre impair choisi au hasard (n'hésitez pas à prendre un nombre premier). Comme les processeurs i86 / amd64 peuvent utiliser une instruction plus courte pour les opérandes s'inscrivant dans un seul octet signé, il y a un avantage de vitesse minuscule pour les multiplicateurs comme 109. Pour minimiser les collisions, prenez quelque chose comme 0x58a54cf5.
L'utilisation de multiplicateurs différents à différents endroits est utile, mais probablement pas suffisante pour justifier le travail supplémentaire.
Objects.hashCode(collection)
devrait être une solution parfaite!