Map.merge() javadoc says,

If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null. This method may be of use when combining multiple mapped values for a key. For example, to either create or append a String msg to a value mapping.

For example, To calculate how many fruits of each type there are in a basket, code is as follows :

public static void main(String[] args) {
    Map<String, Integer> fruitCounts = new HashMap<>();
    List<String> fruitBasket = Arrays.asList("Apple", "Banana", "Apple", "Orange", "Mango", "Orange", "Mango", "Mango");
    for (String fruit : fruitBasket) {
        fruitCounts.merge(fruit, 1/*First fruit of this type*/, (k, v) -> v + 1);
    }
    System.out.println(fruitCounts);
}

There are 2 Apples, 3 Mangos, 2 Oranges and 1 Banana but the actual output is

{Apple=2, Mango=2, Orange=2, Banana=1}

What is wrong with this code ?

2 Answers

6
Mritunjay On Best Solutions

The problem is here

(k, v) -> v + 1

You should be doing

(k, v) -> k + v

If you check the implementation of merge it says, remappingFunction.apply(oldValue, value); means the existing value will be the first parameter in which you should add the same number you initialized it with which comes as a second parameter for that function.

Update

4
Tavo On

Completing @Mritunjay answer's, here's an equivalent using compute where you might be able to see the difference:

fruitCounts.compute(fruit, (k,v) -> v == null ? 1 : v + 1) //computing over the value
fruitCounts.merge(fruit, 1, (oldValue, newValue) -> oldValue + 1) //merging over the value