CodeGym /Java Blog /Java Collections /HashMap computeIfAbsent() method in Java
Author
Volodymyr Portianko
Java Engineer at Playtika

HashMap computeIfAbsent() method in Java

Published in the Java Collections group
Java 8, as many of us know, introduced the Stream API. This is a very useful toolkit, but it has a drawback, it does not include Maps. However, Java 8 added several useful methods to the Map interface itself to reduce the amount of "bad" code. So, if you need to perform some action with the value in the Map, if it exists in it, there is a ComputeIfPresent() method in Java Map. If you need to do something with a value that isn’t in Map, you can use the ComputeIfAbsent() method. We will consider it in this article.

computeIfAbsent() method signature


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
The Map (and HashMap) computeIfAbsent() method takes two parameters. The first parameter is the key. The second parameter is the mappingFunction. In this method the mapping function is only called if the mapping is not presented.

How the computeIfAbsent() method works

As we already know, the Map.computeIfAbsent() method is passed two parameters, the key and the function for calculating the value for this key mappingFunction. Here is the logical algorithm of the method:
  1. The method first checks if the passed key is represented in our Map.
  2. If the key is represented in Map (and it’s not null), then the method does nothing.
  3. Else if the key doesn’t represent in Map (or it’s null) the method calculates the value using mappingFunction to the key.
  4. If the resulting value is not null, then write a key-value pair to map.
Let's write the same logic as code:

if (map.get(key) == null) 
{ 
V newValue = mappingFunction.apply(key); 
if (newValue != null) map.put(key, newValue); 
}

computeIfAbsent() code example

So, if the value is not in the Map, then the method will perform the changes. Let's take a look at a simple example:

import java.util.HashMap;
import java.util.Map;

//map.computeIfAbsent example 
public class ComputeIfAbsentExample {

       public static void main(String[] args) {

           Map<String, String> myMap = new HashMap<>();

           myMap.computeIfAbsent("here is my key", key -> key + ", " + "and this is a new value");

           System.out.println(myMap.get("here is my key"));
       }
}
The output is:
here is my key, and this is a new value
Now let's see what the method will do when there is a given value in the Map. Spoiler alert: It won't do anything.

import java.util.HashMap;
import java.util.Map;

public class ComputeIfAbsentExample2 {

       public static void main(String[] args) {

           Map<String, String> myMap = new HashMap<>();
           myMap.put("here is my key", "and here is my value");

           myMap.computeIfAbsent("here is my key", key -> key + ", " + "and this is a new value");

           System.out.println(myMap.get("here is my key"));
       }
}
Here is the output:
and here is my value
As you can see, the value remains unchanged.

One more ComputeIfAbsent() example

If you are familiar with the concept of caching, the computeIfAbsent() method probably reminds you of something. Let's take a look at a more complex parsing example. Let's call the computeIfAbsent() method twice to make sure that in the first case the value changes, while in the second it doesn't.

import java.util.HashMap;
import java.util.Map;

public class ComputeIfAbsentExample {
   private static Map<String, Long> numbersMap = new HashMap<>();

   public static Long stringToLong(String str) {
       return numbersMap.computeIfAbsent(str, key -> {
           System.out.println("parsing: " + key);
           return Long.parseLong(key);
       });
   }

   public static void main(String[] args) {
       // will print:
       // > parsing: 10
       // > parsing: 25
       // > 10+25=35
       System.out.println("10+25=" + (stringToLong("10") + stringToLong("25")));
       // will print:
       // > parsing: 20
       // > 10+25=45
       // only "20" will be parsed this time, since "25" was already parsed and placed into `numbersMap` map before
       System.out.println("20+25=" + (stringToLong("20") + stringToLong("25")));
       // will print:
       // > 10+20=30
       // no parsing will occur, since both "10" and "20" were already parsed and placed into `numbersMap` map before
       System.out.println("10+20=" + (stringToLong("10") + stringToLong("20")));
   }

}
Here is the output:
parsing: 10 parsing: 25 10+25=35 parsing: 20 20+25=45 10+20=30
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION