Alex
Alex

Reputation: 81

How to use Map.merge for incrementing the counter as value?

I am trying to refactor a method that counts keys in HashMap in a more efficient way by implementing Map.merge(). How can I achieve it on the following code:

 public Map<Character, Integer> countCharacterUsage(String input) {
    Map<Character, Integer> characterToCountUsage = new WeakHashMap<>();
    for (char symbol : input.toCharArray()) {
        if (characterToCountUsage.containsKey(symbol)) {
            int symbolsCount = characterToCountUsage.get(symbol);
            characterToCountUsage.put(symbol, ++symbolsCount);
        } else {
            characterToCountUsage.put(symbol, 1);
        }
    }

    return characterToCountUsage;
}

Upvotes: 0

Views: 773

Answers (2)

Vuk Djapic
Vuk Djapic

Reputation: 886

As per merge() behavior:

 V oldValue = map.get(key);
 V newValue = (oldValue == null) ? value :
          remappingFunction.apply(oldValue, value);
 if (newValue == null)
   map.remove(key);
 else
   map.put(key, newValue);

proper way to do it is

characterToCountUsage.merge(symbol, 1, (oldValue, value) -> oldValue + 1);

But if you want to compress it even more, here is a one liner:

Map<Character, Integer> characterToCountUsage = input.chars().mapToObj(c -> (char) c).collect(Collectors.toMap(Function.identity(), newKey -> 1, (value1, value2) -> value1 + value2));

Upvotes: 1

Ryuzaki L
Ryuzaki L

Reputation: 40008

You can use compute

characterToCountUsage.compute(symbol, (k,v)-> v==null ? 1 : v+1);

Also with merge

characterToCountUsage.merge(symbol,1, (k,v)-> v+1);

Upvotes: 2

Related Questions