example - map string string java
¿Cómo actualizar un valor, dada una clave en un hashmap java? (16)
Supongamos que tenemos un HashMap<String, Integer>
en Java.
¿Cómo actualizo (incremento) el valor entero de la clave de cadena para cada existencia de la cadena que encuentro?
Uno podría quitar y volver a entrar en el par, pero la sobrecarga sería una preocupación.
Otra forma sería simplemente poner el nuevo par y el viejo sería reemplazado.
En este último caso, ¿qué sucede si hay una colisión de código de hash con una nueva clave que estoy tratando de insertar? El comportamiento correcto para una tabla hash sería asignarle un lugar diferente o hacer una lista de él en el grupo actual.
Forma de Java 8:
Puede usar el método computeIfPresent
y proporcionarle una función de mapeo, que se llamará para calcular un nuevo valor basado en uno existente.
Por ejemplo,
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
Alternativamente, puede usar el método de merge
, donde 1 es el valor predeterminado y la función incrementa el valor existente en 1:
words.merge("hello", 1, Integer::sum);
Además, hay un montón de otros métodos útiles, como putIfAbsent
, getOrDefault
, forEach
, etc.
¿Existe el hash (con 0 como valor) o está "puesto" en el mapa en el primer incremento? Si está "puesto" en el primer incremento, el código debería verse así:
if (hashmap.containsKey(key)) {
hashmap.put(key, hashmap.get(key)+1);
} else {
hashmap.put(key,1);
}
Aquí hay respuestas engañosas a esta pregunta que implican que el método put de Hashtable reemplazará el valor existente si la clave existe, esto no es cierto para Hashtable sino para HashMap. Consulte Javadoc para HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
Como no puedo comentar algunas respuestas debido a una menor reputación, publicaré una solución que apliqué.
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
}
}
La forma simplificada de Java 8 :
map.put(key, map.getOrDefault(key, 0) + 1);
Esto utiliza el método de HashMap que recupera el valor de una clave, pero si la clave no se puede recuperar, devuelve el valor predeterminado especificado (en este caso, un ''0'').
Esto es compatible con el núcleo de Java: HashMap <K, V> getOrDefault (clave de objeto, V defaultValue)
La solución de @ Matthew es la más simple y se desempeñará suficientemente bien en la mayoría de los casos.
Si necesita un alto rendimiento, AtomicInteger es una solución mejor para @BalusC.
Sin embargo, una solución más rápida (siempre que la seguridad del hilo no sea un problema) es usar TObjectIntHashMap que proporciona un método de incremento (clave) y utiliza primitivos y menos objetos que la creación de AtomicIntegers. p.ej
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
La solución más limpia sin NullPointerException es:
map.replace(key, map.get(key) + 1);
Puede aumentar como a continuación, pero debe verificar la existencia para que no se lance una NullPointerException
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
Puede que sea un poco tarde pero aquí están mis dos centavos.
Si está utilizando Java 8, puede utilizar el método computeIfPresent . Si el valor de la clave especificada está presente y no es nulo, intentará calcular una nueva asignación dada la clave y su valor actual asignado.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
También podemos hacer uso de otro método putIfAbsent para poner una clave. Si la clave especificada no está ya asociada con un valor (o está asignada a nulo), este método lo asocia con el valor dado y devuelve nulo, de lo contrario devuelve el valor actual.
En caso de que el mapa se comparta a través de subprocesos, entonces podemos utilizar ConcurrentHashMap
y AtomicInteger . Desde el doc:
Un
AtomicInteger
es un valor int que puede actualizarse atómicamente. Un AtomicInteger se usa en aplicaciones como los contadores incrementados atómicamente, y no se puede usar como reemplazo de un Entero. Sin embargo, esta clase extiende el Número para permitir el acceso uniforme por herramientas y utilidades que tratan con clases basadas en números.
Podemos usarlos como se muestra:
final Map<String,AtomicInteger> 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 a observar es que estamos invocando para obtener el valor de la clave B
y luego invocar incrementAndGet()
en su valor, que por supuesto es AtomicInteger
. Podemos optimizarlo ya que el método putIfAbsent
devuelve el valor de la clave si ya está presente:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
En una nota al margen, si planeamos usar AtomicLong entonces, según la documentación bajo alta competencia, el rendimiento esperado de LongAdder es significativamente mayor, a expensas de un mayor consumo de espacio. También revise esta question .
Reemplace Integer
por AtomicInteger
y llame a uno de los métodos incrementAndGet
/ getAndIncrement
.
Una alternativa es envolver un int
en su propia clase MutableInteger
que tiene un método increment()
, solo tiene un problema de seguridad de subprocesos que resolver.
Tratar:
HashMap hm=new HashMap<String ,Double >();
NOTA:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
Puede cambiar la clave o el valor en su hashmap, pero no puede cambiar ambos al mismo tiempo.
Una solución de línea:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
Use un bucle for
para incrementar el índice:
for (int i =0; i<5; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("beer", 100);
int beer = map.get("beer")+i;
System.out.println("beer " + beer);
System.out ....
}
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);
El número entero es tipos de datos primitivos http://cs.fit.edu/~ryan/java/language/java-data.html , por lo que necesita sacarlo, hacer algún proceso y luego devolverlo. Si tiene un valor que no es un tipo de datos Primitivo, solo necesita sacarlo, procesarlo, no es necesario volver a colocarlo en el hashmap.
hashmap.put(key, hashmap.get(key) + 1);
El método put
reemplazará el valor de una clave existente y lo creará si no existe.
map.put(key, map.get(key) + 1);
debería estar bien. Se actualizará el valor de la asignación existente. Tenga en cuenta que esto utiliza el boxeo automático.