Jak zaktualizować wartość podaną w hashmapie java?

Załóżmy, że mamy HashMap<String, Integer> w Javie.

Jak zaktualizować (zwiększyć) wartość całkowitą klucza łańcuchowego dla każdego istnienia znalezionego ciągu?

Można usunąć i ponownie wprowadzić parę, ale nad głową byłoby problemem.
Innym sposobem byłoby po prostu umieścić nową parę i stary zostanie zastąpiony.

W tym drugim przypadku, co się stanie, jeśli dojdzie do kolizji hashcode z nowym kluczem, który próbuję wstawić? Poprawnym zachowaniem hashtable byłoby przypisanie inne miejsce dla niego, lub zrobić z niego listę w bieżącym wiadrze.

Author: Prashant Kumar, 2010-11-11

16 answers

map.put(key, map.get(key) + 1);
Powinno być dobrze. Zaktualizuje wartość dla istniejącego mapowania. Zauważ, że używa się tu auto-boksu.
 767
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-06 01:54:58

Java 8 way:

Możesz użyć metody computeIfPresent i dostarczyć jej funkcję mapowania, która zostanie wywołana do obliczenia nowej wartości na podstawie istniejącej.

Na przykład,

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

Alternatywnie można użyć metody merge, Gdzie 1 jest wartością domyślną, a funkcja zwiększa istniejącą wartość o 1:

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

Ponadto istnieje kilka innych przydatnych metod, takich jak putIfAbsent, getOrDefault, forEach, itd.

 70
Author: damluar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-11 09:15:07
hashmap.put(key, hashmap.get(key) + 1);

Metoda put zastąpi wartość istniejącego klucza i utworzy go, jeśli nie istnieje.

 43
Author: oracleruiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-02 18:53:13

Zastąp Integer przez AtomicInteger i zadzwoń do jednego z incrementAndGet/getAndIncrement metody na nim.

Alternatywą jest zawinięcie int do własnej klasy MutableInteger, która ma metodę increment(), masz tylko wątek do rozwiązania.

 25
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-24 16:25:00

Uproszczony Java 8 sposób:

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

Używa metody HashMap, która pobiera wartość klucza, ale jeśli klucz nie może zostać odczytany, Zwraca określoną wartość domyślną (w tym przypadku '0').

Jest to obsługiwane w jądrze Java: HashMap getOrDefault (klucz obiektu, v defaultValue)

 19
Author: Christopher Bull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 14:48:23

@Mateusz rozwiązanie jest najprostsze i sprawdzi się wystarczająco dobrze w większości przypadków.

Jeśli potrzebujesz wysokiej wydajności, AtomicInteger jest lepszym rozwiązaniem ala @ BalusC.

Jednak szybszym rozwiązaniem (pod warunkiem, że bezpieczeństwo wątku nie jest problemem) jest użycie TObjectIntHashMap , która zapewnia metodę increment(key) i używa prymitywów i mniej obiektów niż tworzenie Atomicintegerów. np.

TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
 16
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 10:13:38

Rozwiązanie jednej linii:

map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
 13
Author: Punktum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:10:46

Możesz zwiększyć jak poniżej, ale musisz sprawdzić istnienie, aby NullPointerException nie został wyrzucony

if(!map.containsKey(key)) {
 p.put(key,1);
}
else {
 p.put(key, map.getKey()+1);
}
 11
Author: isuru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-29 13:32:00

Czy hash istnieje (z wartością 0) czy jest" put " na mapie przy pierwszym przyroście? Jeśli jest "put" przy pierwszym przyroście, kod powinien wyglądać następująco:

if (hashmap.containsKey(key)) {
    hashmap.put(key, hashmap.get(key)+1);
} else { 
    hashmap.put(key,1);
}
 8
Author: sudoBen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-03 20:29:51

Może być trochę późno, ale oto moje dwa centy.

Jeśli używasz Javy 8, możesz użyć metody computeIfPresent. Jeśli wartość dla podanego klucza jest obecna i nie jest null, to próbuje obliczyć nowe mapowanie biorąc pod uwagę klucz i jego bieżącą zmapowaną wartość.

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]

Możemy również użyć innej metody putIfAbsent aby umieścić klucz. Jeżeli podany klucz nie jest jeszcze skojarzony z wartością (lub jest mapowany do wartości null) to metoda ta kojarzy ją z podaną wartością i zwraca null, w przeciwnym wypadku zwraca bieżącą wartość.

W przypadku, gdy mapa jest dzielona między wątki, możemy użyć ConcurrentHashMap i AtomicInteger. Z doc:

An {[4] } jest wartością int, która może być aktualizowana atomicznie. Na AtomicInteger jest używany w aplikacjach takich jak Atomic incremented liczników i nie może być używany jako zamiennik liczby całkowitej. Jednakże, ta klasa rozszerza numer, aby umożliwić jednolity dostęp przez narzędzia i narzędzia, które zajmują się klasami numerycznymi.

Możemy użyć ich jak pokazano:

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]

Należy zauważyć, że wywołujemy get, aby uzyskać wartość klucza B, a następnie wywołujemy incrementAndGet() na jego wartości, która jest oczywiście AtomicInteger. Możemy ją zoptymalizować, ponieważ metoda putIfAbsent Zwraca wartość dla klucza, jeśli jest już obecna:

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

Na marginesie, jeśli planujemy użyć AtomicLong to zgodnie z dokumentacją pod wysokim przepustowość urządzenia LongAdder jest znacznie wyższa, kosztem większego zużycia przestrzeni. Sprawdź również to pytanie .

 5
Author: i_am_zero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-24 07:51:28

Roztwór czyszczący bez NullPointerException to:

map.replace(key, map.get(key) + 1);
 3
Author: Sergey Dirin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 07:14:09

Użyj pętli for, Aby zwiększyć indeks:

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
Author: VanHoutte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-14 21:04:33

Istnieją mylące odpowiedzi na to pytanie, które sugerują, że metoda Hashtable put zastąpi istniejącą wartość, jeśli klucz istnieje, nie jest to prawdą dla Hashtable, ale raczej dla HashMap. Zobacz Javadoc dla HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29

 1
Author: user1048218,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-07 19:31:02

Ponieważ nie mogę skomentować kilku odpowiedzi z powodu mniejszej reputacji, opublikuję rozwiązanie, które zastosowałem.

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
Author: aayush nigam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-28 15:38:36

Try:

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

Uwaga:

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

Możesz zmienić klucz lub wartość w swojej hashmapie, ale nie możesz zmienić obu jednocześnie.

 0
Author: NARAYANAN.M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-18 17:13:29
Integer i = map.get(key);
if(i == null)
   i = (aValue)
map.put(key, i + 1);

Lub

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

Integer to prymitywne typy danych http://cs.fit.edu / ~ryan/java/language/java-data.html , więc musisz go wyjąć, wykonać jakiś proces, a następnie odłożyć z powrotem. jeśli masz wartość, która nie jest prymitywnymi typami danych, wystarczy ją wyjąć, przetworzyć, nie trzeba umieszczać jej z powrotem w hashmapie.

 0
Author: Kreedz Zhen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 00:09:30