2015-07-21 11 views
5
di debug

ho definito un HashMap con il seguente codice:HashMap contiene 4 elementi, ma solo 3 sono presenti in

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

metto 4 prodotti in HashMap. Quando metto a punto, anche se la size è 4, mostra solo 3 elementi:

debugging session

Questa è la lista degli elementi in esso contenuti.

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

Quale può essere il problema?

+4

Um, vedo 4 elementi nella rappresentazione della stringa. Come stai vedendo solo 3? –

+0

Sì, la rappresentazione della stringa è 4 ma sotto la tabella puoi vedere solo 3. Quando cerco di ottenere il valore per la chiave BundleOrderItemEntity @ 1b500292 ... Ricevo NULL in cambio. –

+1

Ah, capisco - hai espanso tutti quei nodi? Fondamentalmente troverai uno di questi link ad un altro ... –

risposta

14

Le mappe di hash gestiscono le collisioni.

Poiché il HashMap è composto solo da 16 secchi, l'hash dell'elemento deve essere ridotta a un numero che si estende tra e (ad esempio hash % 16). Quindi due elementi potrebbero trovarsi nello stesso bucket (lo stesso HashMapNode).

È possibile esaminare ogni HashMapNode per individuare quale contiene due elementi.

+0

Buona direzione enrico. Proverò a scavare di più. Bel problema per arricchire la mia comprensione dell'hashmap. –

+0

@SaurabhKumar sei il benvenuto. Controlla ad esempio [qui] (http://javahungry.blogspot.com/2013/08/hashing-how-hash-map-works-in-java-or.html). –

1

Il meccanismo è spiegato come enrico.bacis, v'è un esempio di riprodurlo:

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

Lì sovrascriviamo hashCode e ritorno codificare che tutti gli oggetti di TT torneranno stesso hashCode .

e siamo in grado di scavare in HashMap.java:

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) { 

possiamo trovato quando abbiamo messo coppia chiave/valore in HashMap, calcolerà hash number dal codice hash dell'oggetto per individuare la posizione dell'elemento nella tabella hash.

quindi se il codice hash degli oggetti è lo stesso, saranno memorizzati nello stesso bucket nella tabella hash. ma questi elementi di confilct saranno comunque memorizzati, perché la loro chiave non è la stessa.

Problemi correlati