it-swarm.com.de

Wie kann ich einen Wert mit einem Schlüssel in einer Java-Hashmap aktualisieren?

Angenommen, wir haben einen HashMap<String, Integer> in Java.

Wie kann ich den ganzzahligen Wert des Zeichenfolgenschlüssels für jedes Vorhandensein der gefundenen Zeichenfolge aktualisieren (inkrementieren)?

Man könnte das Paar entfernen und erneut eingeben, aber Overhead wäre ein Problem.
Eine andere Möglichkeit wäre, einfach das neue Paar zu setzen und das alte zu ersetzen.

Was passiert im letzteren Fall, wenn eine Hashcode-Kollision mit einem neuen Schlüssel auftritt, den ich einzufügen versuche? Das richtige Verhalten für eine Hashtabelle besteht darin, ihr einen anderen Ort zuzuweisen oder eine Liste im aktuellen Bereich zu erstellen.

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

sollte gut sein. Der Wert für die vorhandene Zuordnung wird aktualisiert. Beachten Sie, dass dies das automatische Boxen verwendet.

837

Java 8-Weg:

Sie können die computeIfPresent-Methode verwenden und eine Mapping-Funktion angeben, die aufgerufen wird, um einen neuen Wert basierend auf dem vorhandenen zu berechnen.

Zum Beispiel,

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"));

Alternativ können Sie die merge-Methode verwenden, wobei 1 der Standardwert ist und die Funktion den vorhandenen Wert um 1 erhöht:

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

Darüber hinaus gibt es eine Reihe weiterer nützlicher Methoden, wie putIfAbsent, getOrDefault, forEach usw.

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

Die Methode put wird ersetzen den Wert eines vorhandenen Schlüssels und erstellt ihn, falls er nicht existiert.

46
oracleruiz

Der vereinfachte Java 8 Weg:

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

Hierbei wird die Methode von HashMap verwendet, die den Wert für einen Schlüssel abruft. Wenn der Schlüssel nicht abgerufen werden kann, gibt er den angegebenen Standardwert zurück (in diesem Fall eine '0').

Dies wird in Core Java unterstützt: HashMap <K, V> getOrDefault (Objektschlüssel, V defaultValue)

27

Ersetzen Sie Integer durch AtomicInteger und rufen Sie eine der Methoden incrementAndGet/getAndIncrement an.

Eine Alternative besteht darin, eine int in Ihre eigene MutableInteger-Klasse zu packen, die über eine increment()-Methode verfügt.

26
BalusC

@ Matthews Lösung ist die einfachste und wird in den meisten Fällen gut genug sein.

Wenn Sie hohe Leistung benötigen, ist AtomicInteger eine bessere Lösung, auch unter @BalusC.

Eine schnellere Lösung (Thread-Sicherheit ist jedoch kein Problem) ist die Verwendung von TObjectIntHashMap , die eine inkrementelle (key) -Methode bereitstellt und Primitive und weniger Objekte verwendet, als AtomicIntegers erstellen. z.B.

TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
16
Peter Lawrey

Einzeilige Lösung:

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

Sie können wie unten beschrieben inkrementieren, Sie müssen jedoch nach Existenz suchen, damit keine NullPointerException ausgelöst wird

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

Existiert der Hash (mit 0 als Wert) oder wird er in der ersten Schrittstufe in die Karte "eingefügt"? Wenn es beim ersten Inkrement "put" ist, sollte der Code folgendermaßen aussehen:

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

Es kann etwas spät sein, aber hier sind meine zwei Cents.

Wenn Sie Java 8 verwenden, können Sie die Methode computeIfPresent verwenden. Wenn der Wert für den angegebenen Schlüssel vorhanden ist und nicht null ist, versucht er, eine neue Zuordnung zu berechnen, wenn der Schlüssel und der aktuelle zugeordnete Wert angegeben sind.

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]

Wir können auch eine andere Methode verwenden: putIfAbsent , um einen Schlüssel zu setzen. Wenn der angegebene Schlüssel noch nicht mit einem Wert verknüpft ist (oder dem Wert null zugeordnet ist), ordnet diese Methode diesen Wert dem angegebenen Wert zu und gibt den Wert null zurück. Andernfalls wird der aktuelle Wert zurückgegeben.

Falls die Map von Threads gemeinsam genutzt wird, können wir ConcurrentHashMap und AtomicInteger verwenden. Aus dem Dokument:

Ein AtomicInteger ist ein int-Wert, der atomar aktualisiert werden kann. Ein AtomicInteger wird in Anwendungen wie atomar inkrementiert .__ verwendet. Zähler und kann nicht als Ersatz für eine Ganzzahl verwendet werden. Jedoch, Diese Klasse erweitert Number, um den einheitlichen Zugriff von Tools und .__ zu ermöglichen. Dienstprogramme, die sich mit numerisch basierten Klassen befassen.

Wir können sie wie gezeigt verwenden:

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]

Ein zu beachtender Punkt ist, dass wir get aufrufen, um den Wert für den Schlüssel B zu erhalten, und dann incrementAndGet() für seinen Wert aufrufen, der natürlich AtomicInteger ist. Wir können es optimieren, da die Methode putIfAbsent den Wert für den Schlüssel zurückgibt, falls bereits vorhanden: 

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

Nebenbei bemerkt, wenn wir AtomicLong verwenden wollen, ist der erwartete Durchsatz von LongAdder laut Dokumentation unter hoher Konkurrenzsituation deutlich höher, jedoch auf Kosten eines höheren Speicherplatzbedarfs. Überprüfen Sie auch diese Frage .

5
i_am_zero

Die sauberere Lösung ohne NullPointerException lautet:

map.replace(key, map.get(key) + 1);
4
Sergey Dirin

Verwenden Sie eine for-Schleife, um den Index zu inkrementieren:

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
VanHoutte

Es gibt hier irreführende Antworten auf diese Frage, die implizieren, dass die Hashtable-Methode den vorhandenen Wert ersetzt, wenn der Schlüssel vorhanden ist. Dies gilt nicht für Hashtable, sondern für HashMap. Siehe Javadoc für HashMap http://docs.Oracle.com/javase/7/docs/api/Java/util/HashMap.html#put%28K,%20V%29

1
user1048218

Da ich aufgrund weniger Ruf nicht zu einigen Antworten Stellung nehmen kann, werde ich eine Lösung posten, die ich angewendet habe.

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
aayush nigam

Verwenden Sie die in Java 8 integrierte Funktion 'computeIfPresent'.

Beispiel:

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);
    }
}
0
Rajesh Samson

Versuchen:

HashMap hm=new HashMap<String ,Double >();

HINWEIS:

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

Sie können entweder den Schlüssel oder den Wert in Ihrer Hashmap ändern, aber Sie können nicht beide gleichzeitig ändern. 

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

oder

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

Ganzzahl ist primitive Datentypen http://cs.fit.edu/~ryan/Java/language/Java-data.html , Sie müssen sie also herausnehmen, einen Prozess durchführen und sie dann zurücksetzen. Wenn Sie einen Wert haben, bei dem es sich nicht um primitive Datentypen handelt, müssen Sie ihn nur herausnehmen, verarbeiten und nicht erneut in die Hashmap einfügen.

0
Kreedz Zhen