2016-02-29 16 views
12

Come per la mia comprensione della ArrayList, la capacità di default è 10 e quando cresce al di là di 10, verrà creato un nuovo oggetto di nuova capacità e così via ..Perché il hashCode() di un cambiamento ArrayList ogni volta che si aggiunge un nuovo elemento?

Così per curiosità, ho digitato seguente programma per controllare hashcode() per ArrayList oggetto:

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

Secondo scenario di cui sopra, quando non sono la creazione di capacità iniziale per ArrayList il default sarebbe 10. Così, mentre l'aggiunta di elementi 11, si creerà un nuovo oggetto e aumentare la capacità di ArrayList.

Quando si stampa l'hashcode per l'oggetto ArrayList, ogni volta viene assegnato un nuovo hashcode().

Segue 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 

Secondo il concetto di capacità predefinita, al 10 elemento avrebbe dovuto stampato stesso hashcode() come nessun nuovo oggetto deve essere creato fino a quel punto, ma è non è il caso.

+0

'hashCode()' è legato a 'equals()', che indica che il 2 liste con elementi diversi ma la stessa capacità devono restituire diversi codici hash (che fanno, se si guardano le fonti) – Thomas

+0

Possibile duplicato [Quali problemi devono essere considerati quando si esegue l'override uguale a hashCode in Java?] (Http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in- java) – Raedwald

risposta

32

La hashCode di ArrayList è funzione delle hashCode s di tutti gli elementi memorizzati nel ArrayList, quindi non cambia quando le variazioni di capacità, cambia ogni volta che si aggiunge o rimuove un elemento o mutazione del 'uno degli elementi in un modo che cambia il suo hashCode.

Ecco il Java 8 applicazione (è effettivamente implementata in AbstractList):

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

BTW, questo è il codice esatto che appare nella Javadoc della hashCode() dell'interfaccia List:

Int java.util.List.hashCode()

Restituisce il valore del codice hash per questa lista. Il codice hash di una lista è definita come il risultato del calcolo seguente:

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

Grazie Eran per avermi indicato l'ans corretta :) – suyash

4

Le hashCode di List implementazioni è defined in terms of the hashCode of it's elements. Ciò significa che per ArrayList per essere un conforme List attuazione è hashCodemust cambia quando il suo contenuto cambia.

Più in generale: per gli oggetti mutabili, la hashCode dovrebbe cambiare ogni volta che cambiano in un modo che li renderebbe non equal allo stato precedente.

Si presume che utilizzi lo default hashCode di Object, che non è il caso.

Inoltre, anche se ArrayList non ha attuato hashCode, il codice predefinito hash (noto anche come identity hash code) di un ArrayList non cambierebbe se la matrice interna è stata riassegnata, come oggetto ArrayList stessa rimane lo stesso, basta l'oggetto array interno (a cui non si accede direttamente) verrà sostituito con uno nuovo.

2

La spiegazione di questo può essere trovato cercando in the docs for hashCode

Se due oggetti sono uguali secondo il metodo equals (Object), quindi la chiamata al metodo hashCode su ciascuno dei due oggetti deve produrre lo stesso risultato intero.

Quando un contenuto di ArrayList cambia, cambia anche a quali altri oggetti è uguale. Per soddisfare questa parte del contratto di Object, uno ArrayList deve avere la modifica quando il contenuto lo fa, oppure ogni ArrayList ha lo stesso hashCode. Per renderlo alquanto utile, hanno ovviamente optato per il primo. Questo può essere verificato guardando List's docs.

Restituisce il valore del codice hash per questo elenco. Il codice hash di una lista è definita come il risultato del calcolo seguente:

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

Ciò assicura che list1.equals (list2) implica che list1.hashCode() == list2.hashCode() per qualsiasi due liste, lista1 e lista2, come richiesto dal contratto generale di Object.hashCode().

Problemi correlati