web-dev-qa-db-fra.com

Java Implémentation du tableau HashCode

C'est étrange. Un collègue a posé des questions sur l'implémentation de myArray.hashCode () en Java. Je pensais que je savais mais j'ai ensuite fait quelques tests. Vérifiez le code ci-dessous. L'étrange pense que j'ai remarqué, c'est que lorsque j'ai écrit le premier système, les résultats étaient différents. Notez que c'est presque comme s'il signalait une adresse mémoire et que la modification de la classe déplaçait l'adresse ou quelque chose. Je pensais juste que je partagerais.

int[] foo = new int[100000];
Java.util.Random Rand = new Java.util.Random();

for(int a = 0; a < foo.length; a++) foo[a] = Rand.nextInt();

int[] bar = new int[100000];
int[] baz = new int[100000];
int[] bax = new int[100000];
for(int a = 0; a < foo.length; a++) bar[a] = baz[a] = bax[a] = foo[a];

System.out.println(foo.hashCode() + " ----- " + bar.hashCode() + " ----- " + baz.hashCode() +  " ----- " + bax.hashCode());

// returns 4097744 ----- 328041 ----- 2083945 ----- 2438296
// Consistently unless you modify the class.  Very weird
// Before adding the comments below it returned this:
// 4177328 ----- 4097744 ----- 328041 ----- 2083945


System.out.println("Equal ?? " +
  (Java.util.Arrays.equals(foo, bar) && Java.util.Arrays.equals(bar, baz) &&
  Java.util.Arrays.equals(baz, bax) && Java.util.Arrays.equals(foo, bax)));
49
souLTower

Le Java.lang.ArrayhashCode est héritée de Object, ce qui signifie que le hashcode dépend de la référence. Pour obtenir le code de hachage en fonction du contenu du tableau, utilisez Arrays.hashCode.

Attention cependant, c'est une implémentation de hashcode peu profonde. Une implémentation profonde est également présente Arrays.deepHashCode.

89
MahdeTo

Les tableaux utilisent le code de hachage par défaut, qui est basé sur l'emplacement de la mémoire (mais ce n'est pas nécessairement l'emplacement l'emplacement de la mémoire, car il ne s'agit que d'un int et toutes les adresses mémoire ne conviennent pas) . Vous pouvez le voir en imprimant également le résultat de System.identityHashCode(foo).

Les tableaux ne sont equal que s'ils sont identiques et identiques. Ainsi, les codes de hachage de tableau ne seront égaux, généralement, que s’ils sont identiques et identiques.

4
erickson

L'implémentation par défaut d'Object.hashCode () consiste en effet à renvoyer la valeur du pointeur de l'objet, bien que cela dépende de l'implémentation. Par exemple, une machine virtuelle Java 64 bits peut prendre le pointeur et XOR et les mots de poids fort et faible. Les sous-classes sont encouragées à remplacer ce comportement si cela a du sens.

Cependant, il n'est pas logique d'effectuer des comparaisons d'égalité sur des tableaux mutables. Si un élément change, alors les deux ne sont plus égaux. Pour conserver l'invariant que le même tableau retournera toujours le même hashCode, peu importe ce qui arrive à ses éléments, les tableaux ne remplacent pas le comportement par défaut du code de hachage.

Notez que Java.util.Arrays fournit une implémentation deepHashCode () lorsque le hachage basé sur le contenu du tableau, plutôt que sur l'identité du tableau lui-même, est important.

1
James

Je suis d'accord avec l'utilisation de Java.util.Arrays.hashCode (ou du wrapper générique google guava Objects.hashcode) mais sachez que cela peut causer des problèmes si vous utilisez Terracotta - voir ce lien

1
Carl Pritchett