Come aggiornare un valore, data una chiave in una hashmap java?

Supponiamo di avere una HashMap in Java.

Come aggiornare (incrementare) il valore intero della chiave di stringa per ogni esistenza della stringa che trovo?

Uno potrebbe rimuovere e rientrare nella coppia, ma l’overhead sarebbe una preoccupazione.
Un altro modo sarebbe quello di mettere la nuova coppia e quella vecchia sarebbe stata sostituita.

In quest’ultimo caso, cosa succede se c’è una collisione hashcode con una nuova chiave che sto tentando di inserire? Il comportamento corretto per un hashtable sarebbe assegnare un posto diverso per esso o creare un elenco da esso nel bucket corrente.

 map.put(key, map.get(key) + 1); 

dovrebbe andare bene. Aggiorna il valore per la mapping esistente. Si noti che questo utilizza il box automatico.

Java 8 way:

È ansible utilizzare il metodo computeIfPresent e fornirgli una funzione di mapping, che verrà chiamata per calcolare un nuovo valore in base a quello esistente.

Per esempio,

 Map words = new HashMap<>(); words.put("hello", 3); words.put("world", 4); words.computeIfPresent("hello", (k, v) -> v + 1); System.out.println(words.get("hello")); 

In alternativa, è ansible utilizzare il metodo di merge , in cui 1 è il valore predefinito e la funzione incrementa il valore esistente di 1:

 words.merge("hello", 1, Integer::sum); 

Inoltre, ci sono putIfAbsent altri metodi utili, come putIfAbsent , getOrDefault , forEach , ecc.

 hashmap.put(key, hashmap.get(key) + 1); 

Il metodo put sostituirà il valore di una chiave esistente e lo creerà se non esiste.

Sostituisci Integer con AtomicInteger e chiama uno dei metodi incrementAndGet / getAndIncrement su di esso.

Un’alternativa è quella di racchiudere un int nella tua class MutableInteger che ha un metodo increment() , hai solo un problema di sicurezza del thread da risolvere.

Il modo semplificato di Java 8 :

 map.put(key, map.getOrDefault(key, 0) + 1); 

Questo utilizza il metodo di HashMap che recupera il valore per una chiave, ma se la chiave non può essere recuperata restituisce il valore predefinito specificato (in questo caso uno ‘0’).

Questo è supportato nel core Java: HashMap getOrDefault (Chiave dell’object, V defaultValue)

@ La soluzione di Matthew è la più semplice e funzionerà abbastanza bene nella maggior parte dei casi.

Se hai bisogno di prestazioni elevate, AtomicInteger è una soluzione migliore ala @BalusC.

Tuttavia, una soluzione più rapida (la sicurezza del thread fornita non è un problema) consiste nell’utilizzare TObjectIntHashMap che fornisce un metodo di incremento (chiave) e utilizza le primitive e meno oggetti rispetto alla creazione di AtomicIntegers. per esempio

 TObjectIntHashMap map = new TObjectIntHashMap() map.increment("aaa"); 

Una soluzione di linea:

 map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1); 

È ansible incrementare come di seguito, ma è necessario verificare l’esistenza in modo che non venga generata una NullPointerException

 if(!map.containsKey(key)) { p.put(key,1); } else { p.put(key, map.getKey()+1); } 

L’hash esiste (con 0 come valore) o è “messo” sulla mappa al primo incremento? Se è “messo” al primo incremento, il codice dovrebbe apparire come:

 if (hashmap.containsKey(key)) { hashmap.put(key, hashmap.get(key)+1); } else { hashmap.put(key,1); } 

Potrebbe essere un po ‘tardi ma qui ci sono i miei due centesimi.

Se si utilizza Java 8, è ansible utilizzare il metodo computeIfPresent . Se il valore per la chiave specificata è presente e non nullo, tenta di calcolare una nuova mapping data la chiave e il suo valore mappato corrente.

 final Map map1 = new HashMap<>(); map1.put("A",0); map1.put("B",0); map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1] 

Possiamo anche utilizzare un altro metodo putIfAbsent per inserire una chiave. Se la chiave specificata non è già associata a un valore (o è mappata a null), questo metodo lo associa al valore dato e restituisce null, altrimenti restituisce il valore corrente.

Nel caso in cui la mappa sia condivisa tra thread, possiamo utilizzare ConcurrentHashMap e AtomicInteger . Dal doc:

Un AtomicInteger è un valore int che può essere aggiornato atomicamente. Un object AtomicInteger viene utilizzato in applicazioni come contatori incrementati a livello atomico e non può essere utilizzato come sostituto di un intero. Tuttavia, questa class estende Number per consentire un accesso uniforms da strumenti e utilità che trattano classi basate su numerici.

Possiamo usarli come mostrato:

 final Map map2 = new ConcurrentHashMap<>(); map2.putIfAbsent("A",new AtomicInteger(0)); map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0] map2.get("B").incrementAndGet(); //[A=0, B=1] 

Un punto da osservare è che stiamo invocando get per ottenere il valore per la chiave B e quindi invocando incrementAndGet() sul suo valore che è ovviamente AtomicInteger . Possiamo ottimizzarlo come il metodo putIfAbsent restituisce il valore per la chiave se già presente:

 map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2] 

Una nota a margine, se intendiamo utilizzare AtomicLong, come da documentazione in alto contesa, il throughput previsto di LongAdder è significativamente più alto, a spese di un maggiore consumo di spazio. Controlla anche questa domanda .

La soluzione più pulita senza NullPointerException è:

 map.replace(key, map.get(key) + 1); 

Utilizzare un ciclo for per incrementare l’indice:

 for (int i =0; i<5; i++){ HashMap map = new HashMap(); map.put("beer", 100); int beer = map.get("beer")+i; System.out.println("beer " + beer); System.out .... } 

Ci sono risposte fuorvianti a questa domanda che implicano che il metodo put di Hashtable sostituirà il valore esistente se la chiave esiste, questo non è vero per Hashtable ma piuttosto per HashMap. Vedi Javadoc per HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29

Provare:

 HashMap hm=new HashMap(); 

NOTA:

 String->give the new value; //THIS IS THE KEY else Double->pass new value; //THIS IS THE VALUE 

Puoi cambiare la chiave o il valore nella tua hashmap, ma non puoi cambiarli entrambi allo stesso tempo.

 Integer i = map.get(key); if(i == null) i = (aValue) map.put(key, i + 1); 

o

 Integer i = map.get(key); map.put(key, i == null ? newValue : i + 1); 

L’intero è costituito dai tipi di dati primitivi http://cs.fit.edu/~ryan/java/language/java-data.html , quindi è necessario eliminarlo, elaborarlo e ripristinarlo. se hai un valore che non è un tipo di dati Primitive, devi solo estrarlo, elaborarlo, non è necessario rimetterlo nella hashmap.

Dal momento che non posso commentare alcune risposte a causa della scarsa reputazione, pubblicherò una soluzione che ho applicato.

 for(String key : someArray) { if(hashMap.containsKey(key)//will check if a particular key exist or not { hashMap.put(hashMap.get(key),value+1);// increment the value by 1 to an already existing key } else { hashMap.put(key,value);// make a new entry into the hashmap } }