2015-07-21 13 views
5

Ich habe eine HashMap mit dem folgenden Code definiert dargestellt:HashMap enthält 4 Elemente, sondern nur 3 sind in debug

final Map<OrderItemEntity, OrderItemEntity> savedOrderItems = new HashMap<OrderItemEntity, OrderItemEntity>(); 
final ListIterator<DiscreteOrderItemEntity> li = ((BundleOrderItemEntity) oi).getDiscreteOrderItems().listIterator(); 

while (li.hasNext()) { 
    final DiscreteOrderItemEntity doi = li.next(); 
    final DiscreteOrderItemEntity savedDoi = (DiscreteOrderItemEntity) orderItemService.saveOrderItem(doi); 
    savedOrderItems.put(doi, savedDoi); 
    li.remove(); 
} 

((BundleOrderItemEntity) oi).getDiscreteOrderItems().addAll(doisToAdd); 
final BundleOrderItemEntity savedBoi = (BundleOrderItemEntity) orderItemService.saveOrderItem(oi); 
savedOrderItems.put(oi, savedBoi); 

I in die HashMap setzen 4 Artikel. Wenn ich debuggen, auch wenn die size 4 ist, zeigt es nur drei Elemente:

debugging session

Dies ist die Liste der Elemente enthält.

{[email protected][email protected], [email protected][email protected], [email protected][email protected], [email protected][email protected]} 

Was kann das Problem sein?

+4

Ähm, ich sehe 4 Elemente in der String-Darstellung. Wie siehst du nur 3? –

+0

Ja String-Darstellung ist 4, aber unter Tabelle können Sie nur 3. Wenn ich versuche, den Wert für BundleOrderItemEntity @ 1b500292 Schlüssel zu bekommen ... Ich bekomme NULL zurück. –

+1

Ah, ich sehe - haben Sie alle diese Knoten erweitert? Im Grunde finden Sie einen von ihnen Links zu anderen ... –

Antwort

14

Hashmaps behandeln Kollisionen.

Da Ihr HashMap von nur 16 Eimern zusammengesetzt ist, muss der Hash-Wert des Elements auf eine Anzahl reduziert werden, die zwischen 0 und (z.B. hash % 16) erstreckt. So können zwei Elemente in demselben Bucket sein (dasselbe HashMapNode).

Sie können jede HashMapNode untersuchen, um herauszufinden, welche zwei Elemente enthält.

+0

Gute Richtung enrico. Ich werde versuchen, mehr zu graben. Nettes Problem, mein hashmap Verständnis zu bereichern. –

+0

@SaurabhKumar Sie sind willkommen. Überprüfen Sie zum Beispiel [hier] (http://javahungry.blogspot.com/2013/08/hashing-how-hash-map-works-in-java-or.html). –

1

Der Mechanismus als enrico.bacis erklärt wird, gibt es ein Beispiel, es zu reproduzieren:

public class TestJava { 
    static class TT { 
     private String field; 
     @Override 
     public int hashCode() { 
      return 1; 
     } 
    } 
    public static void main(String[] args) { 
     Map<TT, String> test = new HashMap<>(); 
     TT t1 = new TT(); 
     TT t2 = new TT(); 
     test.put(t1, "test2"); 
     test.put(t2, "test2"); 
     test.put(null, "test2"); 
     test.put(null, "test2"); 

     System.out.println(test.toString()); 
     System.out.println(test.size()); 
    } 
} 

wir hashCode und harte Code Rückkehr In dort außer Kraft setzen, dass alle Objekte von TT gleichen zurück hashCode .

und wir können in HashMap.java graben:

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

static final int hash(Object key) { 
    int h; 
    return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
} 
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, 
       boolean evict) { 

finden wir können, wenn wir Schlüssel/Wert-Paar in HashMap setzen, wird es hash number von Objekt hashcode berechnet das Element Lage in Hash-Tabelle zu finden.

Wenn also der Hash-Code der Objekte gleich ist, werden sie im selben Bucket in der Hash-Tabelle gespeichert. aber diese confilct-Elemente werden immer noch gespeichert, weil ihre Schlüssel nicht gleich sind.

Verwandte Themen