2014-11-14 9 views
7

Java doc says - Gdy liczba wpisów w tabeli hash przekracza iloczyn współczynnika obciążenia i wydajności prądowej, tabela mieszania jest rehashedHashMap pojemność nie wzrosła nawet po osiągnięciu progu

W poniższym programie -

HashMap<Integer, String> map = new HashMap<Integer, String>(); 
int i = 1; 
while(i<16) { 
    map.put(i, new Integer(i).toString()); 
    i++; 
} 

klucz jest typu Integer, przy włożeniu 13 do 15 pojemności elementem HashMap pozostaje 16 i próg pozostaje taka sama jak 12, dlaczego?

Debug ekranu po dodaniu 13th element mapie -

args     String[0] (id=16) 
map HashMap<K,V> (id=19) 
entrySet null 
hashSeed 0 
KeySet  null 
loadFactor 0.75 
modCount 13 
size  13 
table  HashMap$Entry<K,V>[16] (id=25) 
threshold 12 
values  null 
i 14 

[null, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10, 11=11, 12=12, 13=13, null, null] 

HashMap z kluczem typu String - HashMap<String, String> lub niestandardowej klasy - Map<Employee,Integer> pokaz oczekiwanego zachowania na 13 wkładania

+3

Przeczytaj kod. To to wytłumaczy. Możliwe, że coś się zmieniło w implementacji, co oznacza, że ​​javadoc nie jest już * dokładnie * poprawny. Ale to nie jest interesujące (IMO), ponieważ żaden rozsądny programista nigdy nie będzie zależał od dokładnego zachowania zmiany rozmiaru mapy. –

+1

Po prostu próbuję znaleźć powód, dla którego zachowanie implementacji jest inne dla posiadania kluczy jako Integer. Jeśli wypróbuję program HashMap , zmieni on rozmiar mapy na 13. wstawienie – anmolmore

+0

Która wersja Java (w tym aktualizacja)? – m3th0dman

Odpowiedz

5

wygląda to zachowanie jest spowodowane zmienić wewnętrzną implementację metody HashMap PUT w najnowszej wersji Java 7. Po przejściu przez kod źródłowy wielu wersji, znalazłem odpowiedź na moje pytanie:

HashMa wywołuje metodę p put addEntry(), aby dodać nową pozycję -

public V put(K key, V value) { 
    ... 
    int hash = hash(key); 
    int i = indexFor(hash, table.length); 
    ... 
    addEntry(hash, key, value, i); 
    ... 
} 

jdk7-b147 HashMap.addEntry metoda wygląda -

addEntry(int hash, K key, V value, int bucketIndex) { 
    Entry<K,V> e = table[bucketIndex]; 
    table[bucketIndex] = new Entry<>(hash, key, value, e); 
    if (size++ >= threshold) 
     resize(2 * table.length); 
} 

kod źródłowy wersji 1.7.0_67-B01 wygląda -

void addEntry(int hash, K key, V value, int bucketIndex) { 
    if ((size >= threshold) && (null != table[bucketIndex])) { 
     resize(2 * table.length); 
     hash = (null != key) ? hash(key) : 0; 
     bucketIndex = indexFor(hash, table.length); 
    } 
    createEntry(hash, key, value, bucketIndex); 
} 

Tak, w najnowszych wersjach Java, HashMap nie może być zmieniany tylko na podstawie progu. Jeśli wiadro jest pusty wpis będzie nadal wchodzić bez zmiany rozmiaru HashMap

Java 8 mogą mieć różne zachowania, source code of version 8-b132 pokazuje PUT jest całkowicie na nowo wdrożone -

put(K key, V value) { 
    return putVal(hash(key), key, value, false, true); 
} 

putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) { 
    Node<K,V>[] tab; Node<K,V> p; int n, i; 
    if ((tab = table) == null || (n = tab.length) == 0) 
    n = (tab = resize()).length; 
    .... 
} 

final Node<K,V>[] resize() { 
    //many levels of checks before resizing 
} 

doc Java nie mogą być aktualizowane tak często, jak wersje Javy! Dzięki Stephen

Powiązane problemy