Home > Back-end >  Which is one is better map.put(key,map.getOrDefault(key,0) 1) or map.compute(key,(key,value)->val
Which is one is better map.put(key,map.getOrDefault(key,0) 1) or map.compute(key,(key,value)->val

Time:08-20

In the code below , I have added some keys with their values in map. And then I am trying to add value to key "tie" in map. If it is not present in map, then I am setting its value as 1 otherwise and I am adding 1 to its already existing value.


        HashMap<String,Integer> map = new HashMap<>();
        map.put("shoes",100);
        map.put("shirt", 40);
        map.put("pants", 200);
                
        int value;
        //First approach
        value = map.compute("tie",(k,v)->{
            //k is of type String and v is of type Integer
            v = v == null ? 0 : v;
            return v 1;
        });
        //Second approach
        //map.put("tie",map.getOrDefault("tie",0) 1));
        

There are two ways to achieve that

  1. By using compute() method of map
  2. By using getOrDefault() insiste put() method

Can someone please help me which method have better performance and which one is preferred.

CodePudding user response:

The merge method is simpler to use.

If you are using a concurrent implementation of Map, it may also be safer, because it can implement proper synchronization.

Map<String,Integer> = ... ;
map.merge("key", 1, Integer::sum);

CodePudding user response:

Another approach uses counter and computeIfAbsent(k,v) as follows:

import java.util.concurrent.atomic.*;
HashMap<String,AtomicInteger> map = new HashMap<>();

for (String item : List.of("shoes", "shoes", "shirt", "pants", "tie")) {
    map.computeIfAbsent(item, s -> new AtomicInteger()).incrementAndGet();
}
System.out.println("map=" map);

// Prints something like: map={tie=1, shirt=1, pants=1, shoes=2}

CodePudding user response:

Note that HashMap can't store int primitives anyway and it will have to wrap them in an Integer via autoboxing. This is never going to be very efficient if you are updating the value of the integer a lot.

Instead, you might consider using a MutableInt from Apache commons lang instead of Integer. Then you can just get the value and increment it directly. You would need to be careful when handing out references to the value you get as anyone will be able to update the value in the map.

You could also consider using a collections library that implements object-to-int maps directly. For example, fastutils (but there are others): https://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/objects/Object2IntOpenHashMap.html.

  • Related