How and when to use computeIfPresent() and computeIfAbsent() methods of Map interface in Java?

Photo by Retha Ferguson on Pexels.com

Let’s assume you are developing a java app to keep score of goal scores of football players.

Every time a player scores a goal , you call a method with the name of the player and the score gets incremented for that player.

What data structure would you choose for this?

Ideally a map with player name as key and their goal count as value.

Each time a player scores you increment the value against the player’s name.

Let’s see how to implement this .

Let’s create a method scoreGoal which accepts a player name and increments the score.

Let’s call the method for each player when he scores a goal , like below in the main method:

    public static void main(String a[]){


        scoreGoal("Ronaldo");

        scoreGoal("Ravikumar");

        scoreGoal("Batista");


        scoreGoal("Ronaldo");

        scoreGoal("Ronaldo");


        System.out.println(goalMap);

    }

As you see , Ronaldo has scored thrice and others one each.

To implement the above scoreGoal() function , traditionally you might have done something like this:

  static Map<String,Integer> goalMap = new HashMap<>();

    public static void scoreGoal(String player){


        if(goalMap.containsKey(player)){

            int currentGoal = goalMap.get(player);
            goalMap.put(player,currentGoal+1);
        }else{

            goalMap.put(player,1);
        }

    }

The map goalMap is used to store the player and their goal score and is declared as a static class variable.

Each time the method scoreGoal() is called, you check if the player already exists in the map , if yes you retrieve the goal count , increment it and then store it back. If it is not already present then you initialize the count to 1.

We used an if statement , an else statement , did an increment operation , invoked get() method once and put() method twice.

Now let’s see how to optimize this using the methods computeIfAbsent() and computeIfPresent() methods of the Map interface introduced in Java 8.

The scoreGoal() method then gets reduced to :

public static void scoreGoal(String player){

        goalMap.computeIfAbsent(player,goal-> 0);

        goalMap.computeIfPresent(player,(pl,goal)->  goal+1);


    }

Just two lines!

And there is no if statement or else statement. Only two methods of the map interface is called instead of three as in the previous case.

Executing the above code prints the same output as in the previous code:

{Ronaldo=3, Ravikumar=1, Batista=1}

Let’s look a bit into the two methods.

computeIfAbsent():

This method puts a key-value into the goalMap if the key is not already present.

It takes two arguments. The first one is the key and the second one is a mapping function which just returns the value passed to it.

In our case we initialize the goal count to 0 if the player does not already exist in the map.

computeIfPresent()

This method updates the value of a key if already present , else does nothing.

It takes two arguments as well. The first one is the key and the second one is a mapping function which takes a key and the existing value as arguments and returns the new computed value .

In our case we increment the goal count by 1 .

Neat and shorter.

Java 8 has made life easier for java developers in ways like this!


Posted

in

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading