Selon ma compréhension de ArrayList
, la capacité par défaut est de 10 et lorsqu'elle augmente au-delà de 10, elle créera un nouvel objet avec une nouvelle capacité, etc.
Donc, par curiosité, j'ai tapé le programme suivant pour vérifier hashcode()
pour ArrayList
objet:
public class TestCoreJava {
public static void main(String [] args){
ArrayList al = new ArrayList();
for(int i=0;i<15;i++){
al.add("Temp"+i);
System.out.println("Hashcode for "+i+" element "+al.hashCode());
}
}
}
Selon le scénario ci-dessus, lorsque je ne définis pas la capacité initiale pour ArrayList
, la valeur par défaut serait 10. Ainsi, tout en ajoutant le 11e élément, cela créera un nouvel objet et augmentera la capacité de ArrayList
.
Quand j'imprime le hashcode pour l'objet ArrayList
, il donne à chaque fois une nouvelle hashcode()
.
Voici l'o/p:
Hashcode for 0 element 80692955
Hashcode for 1 element -1712792766
Hashcode for 2 element -1476275268
Hashcode for 3 element 1560799875
Hashcode for 4 element 1220848797
Hashcode for 5 element -727700028
Hashcode for 6 element -1003171458
Hashcode for 7 element -952851195
Hashcode for 8 element 607076959
Hashcode for 9 element 1720209478
Hashcode for 10 element -6600307
Hashcode for 11 element -1998096089
Hashcode for 12 element 690044110
Hashcode for 13 element -1876955640
Hashcode for 14 element 150430735
Selon le concept de capacité par défaut, jusqu'au 10ème élément, il devrait avoir imprimé la même hashcode()
car aucun nouvel objet ne doit être créé avant ce point, mais ce n'est pas le cas.
Le hashCode
de ArrayList
est une fonction du hashCode
de tous les éléments stockés dans le ArrayList
, donc il ne change pas lorsque la capacité change, il change chaque fois que vous ajoutez ou supprimez un élément ou mute l'un des éléments d'une manière qui change son hashCode.
Voici l'implémentation Java 8 (elle est en fait implémentée dans AbstractList
):
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
BTW, c'est le code exact qui apparaît dans le Javadoc de hashCode()
de l'interface List
:
int Java.util.List.hashCode ()
Renvoie la valeur du code de hachage pour cette liste. Le code de hachage d'une liste est défini comme étant le résultat du calcul suivant:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
hashCode
des implémentations de List
est défini en termes de hashCode
de ses éléments . Cela signifie que pour que ArrayList
soit une implémentation List
conforme, il faut que hashCode
change lorsque son changements de contenu.
Plus généralement: pour les objets mutables, le hashCode
devrait changer chaque fois qu'ils changent d'une manière qui ne les rendrait pas equal
à leur état précédent.
Vous semblez supposer qu'il utilise le par défaut hashCode
de Object
, ce qui n'est pas le cas.
De plus, même si ArrayList
n'a pas implémenté hashCode
, le code de hachage par défaut (également appelé code de hachage d'identité ) d'un ArrayList
ne serait pas changer si le tableau interne a été réalloué, comme l'objet ArrayList
lui-même reste le même, seul l'objet tableau interne (auquel vous n'avez pas accès directement) sera remplacé par un nouveau.
L'explication peut être trouvée en regardant les documents pour hashCode
Si deux objets sont égaux selon la méthode equals (Object), l'appel de la méthode hashCode sur chacun des deux objets doit produire le même résultat entier.
Lorsqu'un ArrayList
s change de contenu, il change également les autres objets auxquels il est égal. Afin de remplir cette partie du contrat de Object
, un ArrayList
doit avoir son hashCode
changer lorsque le contenu change, ou avoir chaque ArrayList
ont le même hashCode
. Afin de le rendre quelque peu utile, ils ont évidemment opté pour le premier. Cela peut être vérifié en regardant List
's docs .
Renvoie la valeur du code de hachage pour cette liste. Le code de hachage d'une liste est défini comme étant le résultat du calcul suivant:
int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Cela garantit que list1.equals (list2) implique que list1.hashCode () == list2.hashCode () pour deux listes, list1 et list2, comme requis par le contrat général d'Object.hashCode ().