1. Overview

In this tutorial, we’ll discuss the new default method, computeIfAbsent, of the Map interface introduced in Java 8.

Specifically, we’ll look at its signature, usage, and how it handles different cases.

2. Map.computeIfAbsent Method

Let’s start by looking at the signature of computeIfAbsent:

default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)

The computeIfAbsent method takes two parameters. The first parameter is the key, and the second parameter is the mappingFunction. It’s important to know that the mapping function is only called if the mapping isn’t present.

First, it checks if the key is present in the map. If the key is present, and a non-null value is related to the key, then it returns that value:

Map<String, Integer> stringLength = new HashMap<>();
stringLength.put("John", 5);
assertEquals((long)stringLength.computeIfAbsent("John", s -> s.length()), 5);

As we can see, the key “John” has a non-null mapping present, and it returns the value 5. If our mapping function was used, we’d expect the function to return the length of 4.

2.2. Using the Mapping Function to Compute the Value

Furthermore, if the key isn’t present in the map, or the null value is related to the key, then it attempts to compute the value using the given mappingFunction. It also enters the calculated value into the map unless the calculated value is null.

Let’s take a look at the use of the mappingFunction in the computeIfAbsent method:

Map<String, Integer> stringLength = new HashMap<>();
assertEquals((long)stringLength.computeIfAbsent("John", s -> s.length()), 4);
assertEquals((long)stringLength.get("John"), 4);

Since the key “John” isn’t present, it computes the value by passing the key as a parameter to the mappingFunction.

2.3. Mapping Function Returns null

Also, if the mappingFunction returns null, the map records no mapping:

Map<String, Integer> stringLength = new HashMap<>();
assertEquals(stringLength.computeIfAbsent("John", s -> null), null);
assertNull(stringLength.get("John"));

2.4. Mapping Function Throws an Exception

Finally, if the mappingFunction throws an unchecked exception, then the exception is re-thrown, and the map records no mapping:

@Test(expected = RuntimeException.class)
public void whenMappingFunctionThrowsException_thenExceptionIsRethrown() {
    Map<String, Integer> stringLength = new HashMap<>();
    stringLength.computeIfAbsent("John", s -> { throw new RuntimeException(); });
}

We can see that the mappingFunction throws a RuntimeException, which propagates back to the computeIfAbsent method.

3. Conclusion

In this brief article, we focused on the computeIfAbsent method, its signature, and its usage. Finally, we learned how it handles different cases.

As always, all of these code samples are available over on GitHub.