The Map.merge method in Java is a convenient way to simplify various kinds of logic that require updating or modifying values in a map, such as counting occurrences. It works by letting you specify how to combine the old value (if it exists) and the new value (to be added). This is particularly useful for implementing counting logic more concisely.
Here’s how you can use Map.merge to count occurrences:
Key Idea
- If the key doesn’t exist in the map,
mergeinserts it with the given value. - If the key already exists,
mergeuses the provided function (aBiFunction) to combine the existing value and the new value.
Example: Counting Word Occurrences in a String
package org.kodejava.util;
import java.util.HashMap;
import java.util.Map;
public class WordCounter {
public static void main(String[] args) {
String text = "apple banana apple orange banana apple";
// Split the string into words
String[] words = text.split(" ");
// Map to store word counts
Map<String, Integer> wordCounts = new HashMap<>();
// Use Map.merge to simplify counting logic
for (String word : words) {
// Increment count for each word
wordCounts.merge(word, 1, Integer::sum);
}
// Print the word counts
System.out.println(wordCounts);
}
}
Explanation of merge Usage
In the above example:
wordCounts.merge(word, 1, Integer::sum);wordis the key.1is the value to add (for each occurrence of the word).Integer::sumis the combining function that adds the existing value (if present) and the new value.- If the word is already in the map, the count is increased by 1.
- If the word is not in the map, it is added with an initial count of 1.
Advantages of Using Map.merge for Counting
- Conciseness: Avoids the need for verbose
if-elseorcontainsKeychecks. - Thread Safety: Works well in a thread-safe map (e.g.,
ConcurrentHashMap) without requiring additional synchronization. - Readability: The code is clear and easy to understand, as the counting logic is encapsulated in a single line.
Without Map.merge
To see why Map.merge simplifies the code, here’s how the same logic would look without it:
for (String word : words) {
if (wordCounts.containsKey(word)) {
wordCounts.put(word, wordCounts.get(word) + 1);
} else {
wordCounts.put(word, 1);
}
}
As you can see, it’s more verbose and repetitive compared to using merge.
Other Use Cases for Map.merge
- Updating a map with custom logic:
You can combine values in a way that suits your requirements, such as concatenating strings or appending to a list. -
Tracking multiple values:
For example, storing a list of values associated with a key while avoiding null checks:map.merge(key, new ArrayList<>(List.of(value)), (oldList, newList) -> { oldList.addAll(newList); return oldList; }); - Combining maps:
Merge entries from one map into another map using custom logic.
In summary, Map.merge helps to simplify and streamline your counting or updating logic by focusing on what to do with existing and new values, while handling key-insertion logic for you.
