Master Java’s New Map Methods: getOrDefault, forEach, merge & More
Learn how Java 8 introduced powerful Map methods such as getOrDefault, forEach, merge, putIfAbsent, compute, computeIfAbsent, computeIfPresent, and replace, with clear code examples that show how they simplify common tasks like default value handling, iteration, merging entries, and conditional updates.
Introduction
Map is a commonly used data interface in Java. Since JDK 8, several new methods have been added to simplify operations such as default value handling, iteration, merging, and conditional updates.
getOrDefault
This method returns the value associated with a key, or a default value if the key is absent. Example:
<code>private static void testGetOrDefault() {
Map<String, String> map = new HashMap<>(4);
map.put("123", "123");
String key = "key";
String defaultValue = "defaultValue";
// old way
String oldValue = defaultValue;
if (map.containsKey(key)) {
oldValue = map.get(key);
}
System.out.println("oldValue = " + oldValue);
// new way
String newValue = map.getOrDefault(key, defaultValue);
System.out.println("newValue = " + newValue);
}
</code>forEach
The forEach method allows convenient iteration over map entries using a lambda expression.
<code>private static void testForeach() {
Map<String, String> map = new HashMap<>(4);
map.put("123", "123");
// old way
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.printf("old key = %s, value = %s%n", entry.getKey(), entry.getValue());
}
// new way
map.forEach((key, value) -> System.out.printf("new key = %s, value = %s%n", key, value));
}
</code>merge
The merge method combines an existing entry with a new value using a remapping function. Simplified example of counting occurrences in a list:
<code>private static void testMerge() {
Map<String, Integer> cntMap = new HashMap<>(8);
List<String> list = Arrays.asList("apple", "orange", "banana", "orange");
// old way
for (String item : list) {
if (cntMap.containsKey(item)) {
cntMap.put(item, cntMap.get(item) + 1);
} else {
cntMap.put(item, 1);
}
}
// new way
for (String item : list) {
cntMap.merge(item, 1, Integer::sum);
}
}
</code>If the key exists, the value is updated by applying the provided function.
If the key does not exist, the key‑value pair is inserted.
putIfAbsent
Inserts a key‑value pair only when the key is absent or its value is null, avoiding overwriting existing entries.
<code>private static void testPutIfAbsent() {
Map<String, Integer> scoreMap = new HashMap<>(4);
scoreMap.put("Jim", 88);
scoreMap.put("Lily", 90);
// old way
if (!scoreMap.containsKey("Lily")) {
scoreMap.put("Lily", 98);
}
// new way
scoreMap.putIfAbsent("Lily", 98);
}
</code>compute
The compute method takes a key and a remapping function, performing three steps: retrieve the old value (which may be null), compute a new value, and put the new value back into the map.
Obtain the old value for the key.
Apply the provided function to compute a new value.
Put the key with the new value into the map.
Example using compute to count occurrences:
<code>private static void testComputer() {
Map<String, Integer> cntMap = new HashMap<>(8);
List<String> list = Arrays.asList("apple", "orange", "banana", "orange");
// old way
for (String item : list) {
if (cntMap.containsKey(item)) {
cntMap.put(item, cntMap.get(item) + 1);
} else {
cntMap.put(item, 1);
}
}
// new way
for (String item : list) {
cntMap.compute(item, (k, v) -> {
if (v == null) {
v = 1;
} else {
v += 1;
}
return v;
});
}
}
</code>computeIfAbsent
Executes the mapping function only when the key is absent, returning the existing value otherwise. Useful for recursive calculations such as Fibonacci numbers.
<code>private static void testComputerIfAbsent() {
Map<Integer, Integer> fibMap = new ConcurrentHashMap<>(16);
fibMap.put(0, 1);
fibMap.put(1, 1);
System.out.println(fib(5, fibMap));
}
private static Integer fib(Integer index, Map<Integer, Integer> fibMap) {
return fibMap.computeIfAbsent(index, i -> fib(i - 2, fibMap) + fib(i - 1, fibMap));
}
</code>computeIfPresent
This method runs the remapping function only when the key is present, updating the value accordingly.
replace
The replace method updates the value for an existing key; if the key does not exist, nothing happens.
Conclusion
The JDK 8 Map methods can greatly simplify code in appropriate scenarios, though traditional put and get remain useful. Choosing the right method helps keep code concise and elegant.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.