2016-02-09 12 views
8

Voglio fare un istogramma utilizzando un HashMap, la chiave dovrebbe essere il ritardo, il valore la quantità di volte che questo ritardo si verifica. Dubito di utilizzare la funzione HashMapreplace o HashMapput se un ritardo già esistente ha una nuova occorrenza.Differenza tra sostituzione e put per HashMap

ho fatto in questo modo

int delay = (int) (loopcount-packetServed.getArrivalTime()); 
if(histogramType1.containsKey(delay)) 
{ 
    histogramType1.replace(delay, histogramType1.get(delay)+1); 
} 
else 
{ 
    histogramType1.put(delay, 1); 
} 

È corretto? o dovrei usare due volte la funzione put?

+1

[Sostituire] (https://docs.oracle.com/javase/8/docs/api/java/util/HashMap .html # replace-KV-) "Sostituisce la voce per la chiave specificata solo se attualmente è mappata su un valore" –

+0

Quindi dovrei conservare la soluzione di sostituzione? – StudentX

+1

In questo caso non dovrebbe importare poiché se l'elemento esiste dovrebbe avere lo stesso risultato di "put" comunque - poiché "containsKey" è usato "replace" viene chiamato solo se c'è una mappatura. – Thomas

risposta

2

Nel tuo caso, dal momento che prima controlla se il valore è contenuto nella mappa, utilizzando put o replace porta allo stesso risultato.

È possibile utilizzare entrambi, in base a ciò che è più leggibile per voi.

11

Non vi è alcuna differenza in put e replace quando è presente una mappatura corrente per la chiave desiderata. Da replace:

Sostituisce la voce per la chiave specificata solo se è attualmente mappata a un certo valore.

Ciò significa che se c'è già una mappatura per la chiave proposta, sia put e replace aggiorneranno la mappa nello stesso modo. Entrambi restituiranno anche il valore precedente associato alla chiave. Tuttavia, se non ci sono mappature per quella chiave, allora replace sarà un no-op (non farà nulla) mentre put aggiornerà ancora la mappa.


partire con Java 8, nota che si può semplicemente utilizzare

histogramType1.merge(delay, 1, Integer::sum); 

Questo si prenderà cura di ogni condizione. Da merge:

Se la chiave specificata non è già associato a un valore o è associato a null, associa con il dato valore non nullo. Altrimenti, sostituisce il valore associato con i risultati della funzione di rimappatura fornita o rimuove se il risultato è null.

In questo caso, stiamo creando la voce delay -> 1 se la voce non esisteva. Se esiste, viene aggiornato incrementando il valore di 1.

1

Se si guardano le fonti è possibile consultare il seguente (questo è da aggiornamento 11, ma probabilmente non è cambiato molto):

sostituire:

if ((e = getNode(hash(key), key)) != null) { 
    V oldValue = e.value; 
    e.value = value; 
    afterNodeAccess(e); 
    return oldValue; 
}  

messo (interno metodo putVal):

//some code before this to find the node e (similar to getNode(hash(key))) 
if (e != null) { // existing mapping for key 
    V oldValue = e.value; 
    if (!onlyIfAbsent || oldValue == null) //onlyIfAbsent is false here 
    e.value = value; 
    afterNodeAccess(e); 
    return oldValue; 
} 

Come si può vedere, le parti rilevanti del codice fanno di base alleato la stessa cosa dal onlyIfAbsent è false per put e quindi sostituirà sempre il valore.

0

È possibile verificare il comportamento degli altri hanno descritto, con questo:

public class Main { 
    public static void main(String[] args) { 
     Map<String, String> map = new HashMap<>(); 
     map.replace("a", "1"); 
     System.out.println(map.get("a")); 

     map.put("a", "1"); 
     System.out.println(map.get("a")); 

     map.replace("a", "2"); 
     System.out.println(map.get("a")); 
    } 
}