2016-02-29 14 views
12

Jak na moje rozumienie ArrayList zdolność domyślnym jest 10, a kiedy rośnie ponad 10, będzie tworzyć nowy obiekt z nowych zdolności i tak dalej ..Dlaczego parametr hashCode() obiektu ArrayList zmienia się za każdym razem, gdy dodajesz nowy element?

tak z ciekawości wpisałem następujący program do sprawdzenia hashcode() dla ArrayList obiektu:

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

Według powyższej sytuacji, kiedy nie mam możliwości ustawienia początkowe dla ArrayList domyślnym będzie 10. Więc dodając 11th elementu, stworzy nowy obiekt i zwiększenie zdolności do ArrayList.

Po wydrukowaniu kodu skrótu dla obiektu ArrayList za każdym razem nadaje nowy numer hashcode().

Poniżej 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 

Według koncepcji domyślnej pojemności do 10 elementu powinien on wydrukowany samo hashcode() jak nie potrzebuje nowy obiekt ma zostać utworzony do tego momentu, ale jest nie w tym przypadku.

+0

'hashCode()' jest przywiązany do 'równych()', która wskazuje, że 2 Listy z różnych elementów, ale o tej samej pojemności powinien zwracać różne kody hash (co zrobić, jeśli spojrzeć na źródłach) – Thomas

+0

Możliwy duplikat [Jakie problemy należy wziąć pod uwagę, gdy nadpisujesz equals i hashCode w Javie?] (Http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in- java) – Raedwald

Odpowiedz

32

hashCode z ArrayList jest funkcją hashCode s wszystkich elementów przechowywanych w ArrayList, więc nie ulega zmianie, gdy zmienia się pojemność, zmienia się, kiedy tylko dodać lub usunąć element lub mutować jeden z elementów w sposób, który zmienia jego kod hash.

Oto 8 implementacja Javy (nie jest to faktycznie realizowane w AbstractList):

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

BTW, to jest dokładny kod, który pojawia się w Javadoc z hashCode() interfejsu List:

int java.util.List.hashCode()

Zwraca wartość skrótu dla ta lista. Kod skrótu z listy określa się wynikiem następującego wyliczenia:

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

Dzięki Eran za wskazanie mi właściwego ans :) – suyash

4

W hashCode z List implementacje jest defined in terms of the hashCode of it's elements. Oznacza to, że aby ArrayList mogła być zgodna z implementacją, musi zmienić się, gdy zmienia się jej zawartość.

Bardziej ogólnie: w przypadku obiektów zmiennych wartość hashCode powinna się zmieniać, gdy ulegną zmianie w sposób, który uniemożliwi im przejście do poprzedniego stanu.

Wydaje się, że zakładasz, że używa on default hashCode z Object, co nie jest prawdą.

Dodatkowo, nawet jeśli ArrayList nie wdrożył hashCode, domyślny kod hash (znany również jako identity hash code) o ArrayList nie uległaby zmianie, gdyby wewnętrzna tablica została ponownie przydzielone jako przedmiot ArrayList sama pozostaje taka sama, tylko wewnętrzny obiekt tablicy (do którego nie uzyskasz bezpośredniego dostępu) zostanie zastąpiony nowym.

2

Wyjaśnieniem tego może być przyjrzenie the docs for hashCode

Jeśli dwa obiekty są równe metodą Równa (Object), a następnie wywołanie metody hashCode na każdej z tych dwóch przedmiotów musi produkować ten sam wynik całkowity.

Gdy zmienia się zawartość ArrayList, zmienia także inne obiekty, z którymi jest równa. Aby spełnić tę część kontraktu Object, ArrayList musi zmienić ją na hashCode, gdy zawartość się zmieni, lub każdy ArrayList ma to samo hashCode. Aby uczynić ją nieco użyteczną, oczywiście zdecydowali się na tę pierwszą. Można to sprawdzić, patrząc na List's docs.

Powoduje zwrócenie wartości kodu skrótu dla tej listy. Kod skrótu z listy jest zdefiniowane jako wynik następujących obliczeń:

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

Gwarantuje to list1.equals (lista2) wynika, że ​​ list1.hashCode() == list2.hashCode() dla dowolne dwie listy, lista1 i lista2, zgodnie z wymaganiami generalnej umowy Object.hashCode().

Powiązane problemy