'How to increase HashMap value using merge method in Java?

I have the following list and use LinkedHashMap.

I want to increase the value of the key by 1 (if the key is not present in the map, it starts from 0, and I add +1):

int nums[] = new int[]{4, 10, 5, 4, 2, 10};

Map<Integer, Integer> map = new LinkedHashMap<>();

for (int i = 0; i < nums.length; i++) {
    int key = nums[i];
    int value = map.getOrDefault(key, 0) + 1;

    // I want to use merge method, but have no idea 
    // what should be the 3 rd parameter denoted by "<??????>"
    int value = map.merge(key, 1, <??????>)

    map.put(key, value);
}

However, I want to use merge() method, but have no idea what should be the third parameter denoted by "<??????>" (see the code).

So, how can I use merge method in this scenario?



Solution 1:[1]

If only increment/decrement is needed on the integer values, a more economic approach (fewer instances of Integer created) would be to use a mutable integer class (like AtomicInteger) as the value type.

Increment/Decrement would then be trivial:

Map<String, AtomicInteger> map = new HashMap<>();
// Create a mapping for key "foo" if not exists, then increment
int n = map.computeIfAbsent("foo", (k) -> new AtomicInteger())
    .incrementAndGet(); // or addAndGet() or similar

Solution 2:[2]

if the key is not present in the map, it starts from 0 and I add +1

In order to start count from zero you can use method compute(), which expects a key and remappingFunction that allow to compute a new value based on the key and existing value:

int nums[] = new int[]{4, 10, 5, 4, 2, 10};
    
Map<Integer, Integer> map = new LinkedHashMap<>();
    
for (int num : nums) {
    map.compute(num, (k, v) -> v == null ? 0 : v + 1);
}
    
System.out.println(map);

Output:

{4=1, 10=1, 5=0, 2=0}
  • keys 4 and 10 - occur twice and therefore will be associated with the value of 1;
  • keys 5 and 2 - will be encountered only once and therefore get mapped to the value of 0 (as it was required for the keys that were encountered for the first time, i.e. not present in the map)

However, I want to use merge()

With map.merge(num, 1, Integer::sum); a key that hasn't been present in the map will be associated with the value of 1 from the beginning. I.e. the remappingFunction provided as the third argument will not be executed and a new entry comprised from the offered key and value would be placed into a map.

And then when such key will be encountered second, third, etc. time the remappingFunction will be used to combine the old value and a new value (1), i.e. value will be incremented by one.

To achieve the same result as shown above with merge(), we can place condition around merge(). Inside a condition, we can use putIfAbsent() to initialize the entry will 0. If the given key wasn't present, putIfAbsent() will return null, otherwise existing value:

int nums[] = new int[]{4, 10, 5, 4, 2, 10};
    
Map<Integer, Integer> map = new LinkedHashMap<>();
    
for (int num : nums) {
    if (map.putIfAbsent(num, 0) != null) {
        map.merge(num, 1, Integer::sum);
    }
}

Output:

{4=1, 10=1, 5=0, 2=0}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2