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.

493
demandé sur Prashant Kumar 2010-11-11 21:34:01

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.

767
répondu Matthew Flaschen 2012-02-06 01:54:58

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.

70
répondu damluar 2014-09-11 09:15:07
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.

43
répondu oracleruiz 2015-07-02 18:53:13

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.

25
répondu BalusC 2015-07-24 16:25:00

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 getOrDefault (Object key, V defaultValue)

19
répondu Christopher Bull 2016-06-08 14:48:23

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");
16
répondu Peter Lawrey 2013-11-20 10:13:38

Une solution en ligne:

map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
13
répondu Punktum 2016-12-06 18:10:46

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);
}
11
répondu isuru 2015-01-29 13:32:00

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);
}
8
répondu sudoBen 2014-03-03 20:29:51

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 .

5
répondu i_am_zero 2016-05-24 07:51:28

la solution la plus propre sans exception est:

map.replace(key, map.get(key) + 1);
3
répondu Sergey Dirin 2018-01-22 07:14:09

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 ....

}
2
répondu VanHoutte 2012-06-14 21:04:33

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

1
répondu user1048218 2014-08-07 19:31:02

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
   }
}
1
répondu aayush nigam 2017-10-28 15:38:36

, 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.

0
répondu NARAYANAN.M 2012-08-18 17:13:29
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.

0
répondu Kreedz Zhen 2017-09-25 00:09:30