Supposons que nous ayons un HashMap<String, Integer>
en Java.
Comment mettre à jour (incrémenter) la valeur entière de la clé de chaîne pour chaque existence de la chaîne trouvée?
On pourrait enlever et ré-entrer la paire, mais les frais généraux seraient une préoccupation.
Une autre solution consisterait à ne mettre que 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 une nouvelle clé que j'essaie d'insérer? Le comportement correct pour une table de hachage consisterait à lui attribuer un emplacement différent ou à en faire une liste dans le compartiment actuel.
map.put(key, map.get(key) + 1);
ça devrait aller. Il mettra à jour la valeur du mappage existant. Notez que cela utilise la boxe automatique.
Vous pouvez utiliser la méthode computeIfPresent
et lui fournir une fonction de mappage, qui sera appelée pour calculer une nouvelle valeur en fonction de celle 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"));
Alternativement, vous pouvez utiliser la méthode merge
, où 1 est la valeur par défaut et la fonction incrémente la valeur existante de 1:
words.merge("hello", 1, Integer::sum);
En outre, il existe de nombreuses autres méthodes utiles, telles que putIfAbsent
, getOrDefault
, forEach
, etc.
hashmap.put(key, hashmap.get(key) + 1);
La méthode put
va remplace la valeur d'une clé existante et la créera si elle n'existe pas.
La manière simplifiée Java 8:
map.put(key, map.getOrDefault(key, 0) + 1);
Cela utilise la méthode de HashMap qui récupère la valeur d'une clé, mais si la clé ne peut pas être extraite, elle renvoie la valeur par défaut spécifiée (dans ce cas, un «0»).
Ceci est pris en charge dans le noyau Java: HashMap <K, V> getOrDefault (Object Key, V defaultValue)
Remplacez Integer
par AtomicInteger
et appelez l'une des méthodes incrementAndGet
/getAndIncrement
dessus.
Une alternative consiste à envelopper une int
dans votre propre classe MutableInteger
qui a une méthode increment()
, vous avez uniquement un problème de sécurité thread à résoudre.
La solution de @ Matthew est la plus simple et fonctionnera assez bien dans la plupart des cas.
Si vous avez besoin de hautes performances, AtomicInteger est une meilleure solution à l’aide de @BalusC.
Cependant, une solution plus rapide (si la sécurité des threads n'est pas un problème) consiste à utiliser TObjectIntHashMap , qui fournit une méthode d'incrémentation (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 son existence pour qu’une exception NullPointerException ne soit pas levée.
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
Le hachage existe-t-il (avec 0 comme valeur) ou est-il "mis" sur la carte au premier incrément? Si c'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ésente et non nulle, il tente de calculer un nouveau mappage en fonction de la clé et de sa valeur actuelle 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ée à une valeur (ou est mappée sur null), cette méthode l'associe à la valeur donnée et renvoie la valeur null, sinon renvoie la valeur actuelle.
Si la carte est partagée entre plusieurs threads, nous pouvons utiliser ConcurrentHashMap
et AtomicInteger . De la doc:
AtomicInteger
est une valeur int qui peut être mise à jour de manière atomique. Un AtomicInteger est utilisé dans des applications telles que l'incrémentation atomique compteurs, et ne peut pas être utilisé pour remplacer un entier. Toutefois, cette classe étend Number pour permettre un accès uniforme à l'aide d'outils et de utilitaires qui traitent avec des classes numériques.
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 appelons get
pour obtenir la valeur de la clé B
, puis invoquons 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]
Notons que si nous prévoyons d’utiliser AtomicLong , alors que la documentation est très controversée, le débit attendu de LongAdder est considérablement plus élevé, au détriment d’une plus grande consommation d’espace. Vérifiez également cette question .
La solution de nettoyage sans exception NullPointerException est la suivante:
map.replace(key, map.get(key) + 1);
Utilisez une boucle for
pour incrémenter l'index:
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 put de 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
Étant donné que je ne peux pas commenter quelques réponses en raison de la moins bonne réputation, je publierai 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
}
}
Utiliser la fonction intégrée 'computeIfPresent' de Java 8
Exemple:
public class ExampleToUpdateMapValue {
public static void main(String[] args) {
Map<String,String> bookAuthors = new TreeMap<>();
bookAuthors.put("Genesis","Moses");
bookAuthors.put("Joshua","Joshua");
bookAuthors.put("Judges","Samuel");
System.out.println("---------------------Before----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
// To update the existing value using Java 8
bookAuthors.computeIfPresent("Judges", (k,v) -> v = "Samuel/Nathan/Gad");
System.out.println("---------------------After----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
}
}
Essayer:
HashMap hm=new HashMap<String ,Double >();
REMARQUE:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
Vous pouvez modifier 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);
Entier correspond aux types de données primitifs http://cs.fit.edu/~ryan/Java/language/Java-data.html , vous devez donc le supprimer, effectuer un processus, puis le remettre en place. Si vous avez une valeur qui n'est pas de type de données Primitive, il vous suffit de la supprimer, de la traiter, inutile de la replacer dans la table de hachage.