metodo java arraylist collections hashcode

java - metodo - ¿Por qué el hashCode() de un ArrayList cambia cada vez que agregas un nuevo elemento?



hashcode java (3)

Según mi entendimiento de ArrayList , la capacidad predeterminada es 10 y cuando crezca más allá de 10, creará un nuevo objeto con nueva capacidad, etc.

Por curiosidad, escribí el siguiente programa para verificar el hashcode() para el objeto ArrayList :

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()); } } }

De acuerdo con el escenario anterior, cuando no estoy configurando la capacidad inicial para ArrayList el valor predeterminado sería 10. Por lo tanto, al agregar el elemento 11, creará un nuevo objeto y aumentará la capacidad de ArrayList .

Cuando imprimo el código hash para el objeto ArrayList , está dando un hashcode() nuevo hashcode() cada vez.

La siguiente es la 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

De acuerdo con el concepto de capacidad predeterminada, hasta el décimo elemento, debe haber impreso el mismo hashcode() ya que no es necesario crear ningún objeto nuevo hasta ese momento, pero no es el caso.


El hashCode de las implementaciones de la List se define en términos del hashCode de sus elementos . Esto significa que para que ArrayList sea ​​una implementación conforme de la List , su hashCode debe cambiar cuando cambia su contenido.

Más generalmente: para los objetos mutables, el hashCode debe cambiar siempre que cambien de una manera que haga que no sean equal a su estado anterior.

Parece que estás asumiendo que usa el hashCode de hashCode predeterminado de Object , que no es el caso.

Además, incluso si ArrayList no implementó el código hash, el código hash predeterminado (también conocido como el código hash de identidad ) de un ArrayList no cambiaría si la matriz interna se reasignara, ya que el objeto ArrayList sigue siendo el mismo, solo el interno El objeto de matriz (al que no tiene acceso directo) se reemplazará por uno nuevo.


El hashCode of ArrayList es una función del hashCode s de todos los elementos almacenados en ArrayList , por lo que no cambia cuando cambia la capacidad, cambia cada vez que agrega o elimina un elemento o muta uno de los elementos de una manera que cambia su código hash.

Aquí está la implementación de Java 8 (en realidad se implementa en AbstractList ):

public int hashCode() { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); return hashCode; }

Por cierto, este es el código exacto que aparece en el Javadoc de hashCode() de la interfaz de la List :

int java.util.List.hashCode ()

Devuelve el valor del código hash para esta lista. El código hash de una lista se define como el resultado del siguiente cálculo:

int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());


La explicación para esto se puede encontrar mirando los documentos para hashCode

Si dos objetos son iguales según el método equals (Objeto), entonces llamar al método hashCode en cada uno de los dos objetos debe producir el mismo resultado entero.

Cuando los contenidos de un ArrayList cambian, también cambia a qué otros objetos es igual. Para cumplir con esta parte del contrato de Object , una ArrayList necesita que su hashCode de hashCode cambie cuando lo hace el contenido, o que cada ArrayList tenga el mismo hashCode . Para hacerla algo útil, obviamente optaron por la primera. Esto puede verificarse mirando los documentos de la List .

Devuelve el valor del código hash para esta lista. El código hash de una lista se define como el resultado del siguiente cálculo:

int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

Esto garantiza que list1.equals (list2) implica que list1.hashCode () == list2.hashCode () para cualquiera de las dos listas, list1 y list2, como lo requiere el contrato general de Object.hashCode ().