Kaip atnaujinti vertę, atsižvelgiant į „jash hashmap“ raktą?

Tarkime, Java turi HashMap<String, Integer> .

Kaip atnaujinti (padidinti) eilutės rakto sveiko skaičiaus vertę kiekvienai eilutės, kurią aš rasiu, egzistavimui?

Galite ištrinti ir iš naujo įvesti porą, bet pridėtinės išlaidos bus problemos.
Kitas būdas - tiesiog įdėti naują porą, o senas bus pakeistas.

Pastaruoju atveju, kas atsitiks, jei susidūrė su hashcode su nauju raktu, kurį bandau įterpti? Teisingas maišos lentelės elgesys būtų priskirti kitai vietai arba sudaryti sąrašą iš dabartinio kibiro.

524
11 нояб. nustatė laertis 11 nov. 2010-11-11 21:34 '10, 21:34, 2010-11-11 21:34
@ 17 atsakymų
 map.put(key, map.get(key) + 1); 

turėtų būti geras. Jis atnaujins esamų žemėlapių vertę. Atkreipkite dėmesį, kad šiuo atveju naudojamas automatinis >

825
11 нояб. Atsakymą pateikė Matthew Flaschen lapkričio 11 d. 2010-11-11 21:39 '10, 21:39, 2010-11-11 21:39

„Java 8“ būdas:

Jūs galite naudoti computeIfPresent metodą ir suteikti jam atitikimo funkciją, kuri bus paskirta apskaičiuoti naują vertę pagal esamą.

Pavyzdžiui

 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")); 
border=0

Arba galite naudoti merge metodą, kur 1 yra numatytoji vertė, o funkcija padidina esamą vertę 1:

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

Be to, yra daug kitų naudingų metodų, pvz., „ putIfAbsent , „ getOrDefault , „ forEach ir kt.

79
11 сент. atsakymas duotas damluar 11 sep . 2014-09-11 12:15 '14, 12:15 2014-09-11 12:15
 hashmap.put(key, hashmap.get(key) + 1); 

put metodas pakeis esamo rakto vertę ir ją sukurs, jei jo nėra.

45
03 нояб. atsakymas duotas oracleruiz lapkričio 03 d. 2011-11-03 19:35 '11, 19:35, 2011-11-03 19:35

„Java 8“ supaprastintas būdas:

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

Tokiu atveju naudojamas „HashMap“ metodas, kuris nuskaito rakto vertę, tačiau jei raktas negali būti atkurtas, jis grąžina nurodytą numatytąją vertę (šiuo atveju reikšmę „0“).

Tai palaikoma „Java“ branduolyje: „ HashMap“ <K, V> getOrDefault (objekto raktas, V defaultValue)

26
08 июня '16 в 17:48 2016-06-08 17:48 Atsakymą pateikė Christopher Bull birželio 8–16 d. 17:48 2016-06-08 17:48

Pakeiskite „ Integer su „ AtomicInteger ir paskambinkite vienu iš „ getAndIncrement / getAndIncrement .

Alternatyva yra suvynioti int savo savo „ MutableInteger klasėje, kurios metodas yra increment() .

26
11 нояб. Atsakymą pateikė BalusC 11 lapkričio. 2010-11-11 21:37 '10, 21:37, 2010-11-11 21:37

„@Matthew“ sprendimas yra paprasčiausias ir daugeliu atvejų veiks gerai.

Jei jums reikia gerų rezultatų, „AtomicInteger“ yra geriausias sprendimas „@ @ @BalusC“.

Tačiau greitesnis sprendimas (darant prielaidą, kad sriegių sauga nėra problema) yra naudoti TObjectIntHashMap , kuris suteikia prieaugio (raktų) metodą ir naudoja primityvius ir mažiau objektų nei kuriant „AtomicIntegers“. Pavyzdžiui.

 TObjectIntHashMap<String> map = new TObjectIntHashMap<String>() map.increment("aaa"); 
16
11 нояб. Peter Lawrey atsakymas, lapkričio 11 d. 2010-11-11 21:56 '10, 21:56, 2010-11-11 21:56

Vienos eilutės sprendimas:

 map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1); 
14
06 дек. Atsakymas duotas Punktum 06 Dec 2016-12-06 21:10 '16 at 9:10 pm 2016-12-06 21:10

Galite padidinti, kaip parodyta žemiau, tačiau turite patikrinti egzistavimą, kad pašalintumėte „NullPointerException“.

 if(!map.containsKey(key)) { p.put(key,1); } else { p.put(key, map.getKey()+1); } 
11
09 авг. atsakymas duotas isuru 09 rug. 2013-08-09 21:57 '13, 9:57 pm 2013-08-09 21:57

Ar yra maišos (su 0 kaip reikšmė) arba ar jis „įterpiamas“ žemėlapyje pirmojo prieaugio metu? Jei pirmasis žingsnis yra „įdėtas“, kodas turėtų atrodyti taip:

 if (hashmap.containsKey(key)) { hashmap.put(key, hashmap.get(key)+1); } else { hashmap.put(key,1); } 
8
03 марта '14 в 23:29 2014-03-03 23:29 atsakymas pateikiamas sudoBen 03 kovo 14 d. 23:29 2014-03-03 23:29

Tai gali būti šiek tiek vėlai, bet čia yra mano du centai.

Jei naudojate „Java 8“, galite naudoti computeIfPresent metodą. Jei nurodytam klavišui yra reikšmė, o ne nulinė, ji bando apskaičiuoti naują atvaizdavimą pagal klavišą ir dabartinę rodymo vertę.

 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] 

Taip pat galime naudoti kitą „ PutIfAbsent“ metodą raktui įdėti. Jei nurodytas raktas dar nėra susietas su verte (arba priskiriamas nuliui), šis metodas susieja jį su nurodyta verte ir grąžina nulį, kitaip jis grąžina dabartinę vertę.

Jei žemėlapis paskirstomas srautuose, galime naudoti „ ConcurrentHashMap ir „ AtomicInteger“ . Iš dokumento:

AtomicInteger yra int vertė, kurią galima atnaujinti atominiu būdu. „AtomicInteger“ naudojamas tokiose programose kaip atominiai didinimo skaitikliai ir negali būti naudojama kaip „Integer“ pakeitimo priemonė. Tačiau ši klasė praplečia skaičių, kad suteiktų vienodą prieigą naudojant įrankius ir komunalines paslaugas, veikiančias skaitines klases.

Galime juos naudoti kaip parodyta:

 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] 

Vienas dalykas, kurį reikia pastebėti, yra tai, kad mes vadiname get raktų B vertę, o paskui skambinkite incrementAndGet() pagal jo vertę, kuri, žinoma, yra „ AtomicInteger . Galime jį optimizuoti, nes „ putIfAbsent metodas grąžina rakto vertę, jei jis jau yra:

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

Pastabos pusėje, jei planuojame naudoti „ AtomicLong“ , tuomet pagal aukštą konkurencijos dokumentaciją, tikėtina „ LongAdder“ našta yra daug didesnė dėl didesnio erdvės suvartojimo. Taip pat patikrinkite šį klausimą .

5
24 мая '16 в 10:51 2016-05-24 10:51 Atsakymas pateikiamas i_am_zero gegužės 24, 16 d. 10:51 2016-05-24 10:51

Švaresnis sprendimas be „NullPointerException“:

 map.replace(key, map.get(key) + 1); 
4
22 янв. Sergejo Dirino atsakymas, pateiktas sausio 22 d 2018-01-22 10:14 '18, 10:14 2018-01-22 10:14

Naudokite „loop“, kad padidintumėte 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
14 июня '12 в 23:40 2012-06-14 23:40 atsakymas suteiktas VanHoutte birželio 14 d., 12 val. 23:40 2012-06-14 23:40

Kadangi negaliu komentuoti kelių atsakymų dėl mažesnės reputacijos, paskelbsiu taikomą sprendimą.

 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
28 окт. Atsakymą pateikia „ aayush nigam“ spalio 28 d 2017-10-28 18:38 '17 at 18:38 2017-10-28 18:38

Čia yra klaidinančių atsakymų, rodančių, kad „Hashtable“ metodas pakeis esamą vertę, jei raktas egzistuoja, tai netiesa „Hashtable“, o „HashMap“. Žr. „Javadoc for HashMap“ http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29

1
07 авг. atsakymą pateikė user1048218 07 rug . 2014-08-07 22:31 '14, 10:31 pm 2014-08-07 22:31

Pabandykite:

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

Pastaba:

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

Galite keisti raktą arba vertę savo maišos žemėlapyje, tačiau negalite keisti abiejų tuo pačiu metu.

0
18 авг. Atsakymas pateikiamas NARAYANAN.M 18 rug . 2012-08-18 13:37 '12 13:37 2012-08-18 13:37
 Integer i = map.get(key); if(i == null) i = (aValue) map.put(key, i + 1); 

arba

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

Integer yra primityvūs duomenų tipai http://cs.fit.edu/~ryan/java/> , todėl jums reikia jį ištraukti, atlikti tam tikrą procesą ir grąžinti jį atgal. jei turite vertę, kuri nėra primityvus duomenų tipas, jums reikia tik jį pašalinti, apdoroti, nereikia grąžinti į maišos žemėlapį.

Naudokite „Java8“ integruotą „computeIfPresent“ funkciją

Pavyzdys:

 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
06 февр. atsakymas, kurį pateikė Rajesh Samson 2019-02-06 14:51 '19, 14:51 pm 2019-02-06 14:51

Kiti klausimai apie „ arba Užduoti klausimą