Comment mettre à jour une valeur, avec une clé dans un HashMap java?
supposons que nous ayons un HashMap<String, Integer>
en Java.
comment mettre à jour (incrémenter) la valeur entière de la clé string pour chaque existence de la chaîne que je trouve?
on pourrait retirer et réintégrer le couple, mais les frais généraux seraient une préoccupation.
Une autre façon serait de simplement mettre la nouvelle paire et l'ancienne serait remplacée.
dans ce dernier cas, que se passe-t-il s'il y a une collision de hashcode avec un nouveau clé je suis en train de les insérer? Le comportement correct pour un hashtable serait d'assigner un endroit différent pour lui, ou faire une liste hors de lui dans le seau courant.
16 réponses
map.put(key, map.get(key) + 1);
devrait aller. Il mettra à jour la valeur de la cartographie existante. Notez que cela utilise l'auto-boxe.
Java 8:
vous pouvez utiliser la méthode computeIfPresent
et lui fournir une fonction de cartographie, qui sera appelée à calculer une nouvelle valeur basée sur une valeur existante.
par exemple,
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"));
Aussi, vous pouvez utiliser merge
la méthode, où 1 est la valeur par défaut et la fonction incrémente la valeur existante par 1:
words.merge("hello", 1, Integer::sum);
En outre, il ya un tas d'autres méthodes utiles, tels comme putIfAbsent
, getOrDefault
, forEach
, etc.
hashmap.put(key, hashmap.get(key) + 1);
La méthode put
sera remplacer la valeur d'une clé existante et à créer si elle n'existe pas.
remplacer Integer
par AtomicInteger
et appeler l'une des méthodes incrementAndGet
/ getAndIncrement
.
une alternative est d'envelopper un int
dans votre propre classe MutableInteger
qui a une méthode increment()
, vous avez seulement un souci de sécurité thread à résoudre encore.
simplifié Java 8 :
map.put(key, map.getOrDefault(key, 0) + 1);
utilise la méthode de HashMap qui récupère la valeur d'une clé, mais si la clé ne peut pas être récupérée, elle renvoie la valeur par défaut spécifiée (dans ce cas un '0').
ceci est supporté dans le noyau Java: HashMap
la solution de @ Matthew est la plus simple et performera assez bien dans la plupart des cas.
si vous avez besoin de hautes performances, AtomicInteger est une meilleure solution ala @BalusC.
cependant, une solution plus rapide (à condition que la sécurité du fil ne soit pas un problème) est d'utiliser TObjectIntHashMap qui fournit une méthode incrémentielle(clé) et utilise des primitives et moins d'objets que la création D'AtomicIntegers. par exemple
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
Une solution en ligne:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
vous pouvez incrémenter comme ci-dessous, mais vous devez vérifier l'existence afin qu'une exception NullPointerException ne soit pas jeté
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
le hachage existent (avec 0 comme valeur) ou est-il "mettre" à la carte sur le premier incrément? S'il est "mis" sur le premier incrément, le code devrait ressembler à:
if (hashmap.containsKey(key)) {
hashmap.put(key, hashmap.get(key)+1);
} else {
hashmap.put(key,1);
}
C'est peut-être un peu tard, mais voici mes deux cents.
si vous utilisez Java 8, Vous pouvez utiliser la méthode computeIfPresent . Si la valeur de la clé spécifiée est présent et non vide alors qu'il tente de calculer une nouvelle cartographie donné la clé et sa valeur mappée.
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]
nous pouvons également utiliser une autre méthode putIfAbsent pour mettre une clé. Si la clé spécifiée n'est pas déjà associé à une valeur (ou est mappé à null) alors cette méthode l'associe à la valeur donnée et renvoie null, sinon renvoie la valeur courante.
dans le cas où la carte est partagée à travers les threads, alors nous pouvons faire usage de ConcurrentHashMap
et AtomicInteger . Extrait du doc:
Un
AtomicInteger
est une valeur int qui peuvent être mis à jour automatiquement. Un AtomicInteger est utilisé dans des applications telles que automatiquement incrémenté compteurs, et ne peut pas être utilisé comme un remplacement pour un Entier. Cependant, cette classe étend le nombre pour permettre un accès uniforme par les outils et les utilitaires qui traitent des classes à base numérique.
Nous pouvons les utiliser comme indiqué:
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 point à observer est que nous invoquons get
pour obtenir la valeur de la clé B
et ensuite invoquer incrementAndGet()
sur sa valeur qui est bien sûr AtomicInteger
. Nous pouvons l'optimiser car la méthode putIfAbsent
renvoie la valeur de la clé si elle est déjà présente:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
sur une note de côté si nous prévoyons d'utiliser AtomicLong puis selon la documentation sous haute assertion le débit attendu de LongAdder est considérablement plus élevé, au détriment de la consommation d'espace plus élevée. Aussi, cochez cette question .
la solution la plus propre sans exception est:
map.replace(key, map.get(key) + 1);
utilisez une boucle for
pour incrémenter l'indice:
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 ....
}
il y a des réponses trompeuses à cette question ici qui impliquent que la méthode de put Hashtable remplacera la valeur existante si la clé existe, ce n'est pas vrai pour Hashtable mais plutôt pour HashMap. Voir Javadoc pour HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V % 29
depuis que je ne peux pas commenter à quelques réponses en raison de moins de réputation, je vais poster une solution que j'ai appliquée.
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
}
}
, Essayez:
HashMap hm=new HashMap<String ,Double >();
NOTE:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
vous pouvez changer la clé ou la valeur dans votre hashmap, mais vous ne pouvez pas changer les deux en même temps.
Integer i = map.get(key);
if(i == null)
i = (aValue)
map.put(key, i + 1);
ou
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
Integer est un type de données primitif http://cs.fit.edu/~ryan/java/language/java-data.html , donc vous devez le sortir, faire un peu de processus, puis le remettre en place. si vous avez une valeur qui n'est pas des types de données primitifs, vous n'avez qu'à l'extraire, la traiter, pas besoin de la remettre dans le hashmap.