Hoe een waarde bijwerken, gegeven een sleutel in een hashmap?

Stel dat we een HashMap<String, Integer>in Java hebben.

Hoe update (verhoog) ik de integer-waarde van de string-key voor elk bestaan ​​van de string die ik vind?

Je zou het paar kunnen verwijderen en opnieuw invoeren, maar overhead zou een probleem zijn.
Een andere manier zou zijn om gewoon het nieuwe paar te plaatsen en het oude te vervangen.

Wat gebeurt er in het laatste geval als er een hashcode-botsing is met een nieuwe sleutel die ik probeer in te voegen? Het juiste gedrag voor een hashtabel zou zijn om er een andere plaats voor toe te wijzen, of er een lijst van te maken in de huidige bucket.


Antwoord 1, autoriteit 100%

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

zou goed moeten zijn. Het zal de waarde voor de bestaande toewijzing bijwerken. Merk op dat dit auto-boxing gebruikt. Met behulp van map.get(key)krijgen we de waarde van de bijbehorende sleutel, waarna u kunt updaten met uw vereiste. Hier ben ik aan het updaten om de waarde met 1 te verhogen.


Antwoord 2, autoriteit 12%

Java 8 manier:

U kunt de methode computeIfPresentgebruiken en deze een mapping-functie geven, die wordt aangeroepen om een ​​nieuwe waarde te berekenen op basis van de bestaande.

Bijvoorbeeld

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

Als alternatief kunt u de methode mergegebruiken, waarbij 1 de standaardwaarde is en de functie de bestaande waarde met 1 verhoogt:

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

Daarnaast zijn er nog een heleboel andere handige methoden, zoals putIfAbsent, getOrDefault, forEach, enz.


Antwoord 3, autoriteit 5%

De vereenvoudigde Java 8-manier:

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

Dit gebruikt de methode van HashMap die de waarde voor een sleutel ophaalt, maar als de sleutel niet kan worden opgehaald, wordt de opgegeven standaardwaarde geretourneerd (in dit geval een ‘0’).

Dit wordt ondersteund in core Java: AtomicIntegeren roep een van de methoden incrementAndGet/getAndIncrementerop aan.

Een alternatief is om een ​​intin uw eigen MutableInteger-klasse in te pakken die een increment()-methode heeft, u heeft alleen een probleem met de threadveiligheid nog op te lossen.


Antwoord 6, autoriteit 2%

Eenregelige oplossing:

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

Antwoord 7, autoriteit 2%

De oplossing van @Matthew is de eenvoudigste en zal in de meeste gevallen goed genoeg presteren.

Als je hoge prestaties nodig hebt, is AtomicInteger een betere oplossing, ala @BalusC.

Echter, een snellere oplossing (mits de veiligheid van threads geen probleem is) is het gebruik van TObjectIntHashMapdie een increment(key)-methode biedt en primitieven en minder objecten gebruikt dan het maken van AtomicIntegers. bijv.

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

Antwoord 8

U kunt verhogen zoals hieronder, maar u moet controleren op bestaan ​​zodat er geen NullPointerException wordt gegenereerd

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

Antwoord 9

Bestaat de hash (met 0 als waarde) of wordt deze bij de eerste stap op de kaart “geplaatst”? Als het op de eerste stap wordt gezet, zou de code er als volgt uit moeten zien:

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

Antwoord 10

Het is misschien wat laat, maar hier zijn mijn twee cent.

Als u Java 8 gebruikt, kunt u gebruik maken van computeIfPresentmethode. Als de waarde voor de opgegeven sleutel aanwezig en niet-null is, wordt geprobeerd een nieuwe toewijzing te berekenen op basis van de sleutel en de huidige toegewezen waarde.

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]

We kunnen ook een andere methode gebruiken putIfAbsentom een ​​sleutel in te voeren. Als de opgegeven sleutel nog niet is gekoppeld aan een waarde (of is toegewezen aan null), dan koppelt deze methode deze aan de gegeven waarde en retourneert null, anders retourneert de huidige waarde.

In het geval dat de kaart door verschillende threads wordt gedeeld, kunnen we gebruik maken van ConcurrentHashMapen AtomicInteger. Uit het document:

Een AtomicIntegeris een int-waarde die atomair kan worden bijgewerkt. Een
AtomicInteger wordt gebruikt in toepassingen zoals atomair incrementeel
tellers, en kan niet worden gebruikt als vervanging voor een geheel getal. Echter,
deze klasse breidt Number wel uit om uniforme toegang door tools mogelijk te maken en
hulpprogramma’s die omgaan met numeriek gebaseerde klassen.

We kunnen ze gebruiken zoals weergegeven:

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]

Een punt om in de gaten te houden is dat we getaanroepen om de waarde voor sleutel Bte krijgen en vervolgens incrementAndGet()aanroepen op zijn waarde die is natuurlijk AtomicInteger. We kunnen het optimaliseren omdat de methode putIfAbsentde waarde voor de sleutel retourneert als deze al aanwezig is:

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

Terzijde als we van plan zijn om AtomicLongdan volgens documentatie onder hoge betwisting verwachte doorvoer van LongAdderis aanzienlijk hoger, ten koste van een hoger ruimteverbruik. Bekijk ook deze vraag.


Antwoord 11

De schonere oplossing zonder NullPointerException is:

map.replace(key, map.get(key) + 1);

Antwoord 12

Omdat ik op een paar antwoorden niet kan reageren vanwege minder reputatie, zal ik een oplossing posten die ik heb toegepast.

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

Antwoord 13

Gebruik een forlus om de index te verhogen:

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

Antwoord 14

Er zijn hier misleidende antwoorden op deze vraag die impliceren dat de Hashtable put-methode de bestaande waarde zal vervangen als de sleutel bestaat, dit geldt niet voor Hashtable maar eerder voor HashMap. Zie Javadoc voor HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29


Antwoord 15

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

of

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

Geheel getal is primitieve gegevenstypen http://cs.fit .edu/~ryan/java/language/java-data.html, dus je moet het eruit halen, een proces uitvoeren en het dan terugplaatsen. als u een waarde heeft die geen primitief gegevenstype is, hoeft u deze er alleen uit te halen, te verwerken en niet terug in de hashmap te plaatsen.


Antwoord 16

Gebruik Java8 ingebouwde functie ‘computeIfPresent’

Voorbeeld:

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

Antwoord 17

Probeer:

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

OPMERKING:

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

U kunt de sleutel of de waarde in uw hashmap wijzigen, maar u kunt niet beide tegelijkertijd wijzigen.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

3 × one =

Other episodes