Wednesday, May 10, 2023

How to update value for a given key in HashMap - Java 8 getOrDefault() example

Suppose you have a Map of String keys and Integer values e.g. word and their count. You are reading from a file and storing count of each word into an HashMap, if a word already exists you want to update the value by incrementing existing value by 1, how will you do that in Java? Does HashMap provides an update() method to perform such operations? Well, No. HashMap doesn't provide an update method but you can use the same put() method to both insert and update a mapping. If you call the put(key, value) method with a key which already exists in the HashMap then instead of adding a new mapping, it updates the value of existing mapping. For example, if the key "Java" is mapped to the value 1000 in a map then calling put("Java", 1001) will replace the old value with the new value, instead of adding another entry. 

Remember, you cannot have duplicate keys in a HashMap, that's why you get a Set when you retrieve all keys and a Collection when you retrieve all values, because values can be duplicated in HashMap.

Btw, replacing a value is little bit different than updating a value. In case of replace, you know the new value and you don't need to retrieve the old value associated with the key, but in case of update you first need to retrieve the existing value for a given key, modify it e.g. increment or decrement it by 1 and then put it back again into the map. 

This is like ++ operator, which first read value, increment it and then write it back to the variable.

When you ask a Java programmer to write code for updating value for given key in HashMap, you will see many versions, many of them are subject to NullPointerException as shown below:

hashmap.put(key, hashmap.get(key) + 1);

This code will throw NullPointerException for a non-existing key because null cannot be autoboxed into zero hence the null + 1 code will throw NullPointerException. Another similar version is 

int value = hashmap.get(key);
if (value == null) {
    hashmap.put(key, 0);
} else {
    hashmap.put(key, value + 1);
}

This code will also throw null pointer exception because null cannot be auto-boxed into an int variable. The right way, to update a value in HashMap in Java is first to check if key exists or not and then retrieve value as shown in following example:

if (hashmap.containsKey(key)) {
    hashmap.put(key, hashmap.get(key) + 1);
} else {
    hashmap.put(key, 1);
}

This code will not throw NullPointerException as we are checking for the existence of key before we retrieve value from the Map.

Btw, Java 8 has added a useful method called getOrDefault(), which can further simply above code. This method returns the value to which the specified key is mapped, or default value, if this map contains no mapping for the key. You can rewrite the above code to update a value in HashMap in just one line in Java 8 as shown below:

map.put(key, map.getOrDefault(key, 0) + 1);

This code uses the getOrDefault() method of HashMap that retrieves the value for a key, but if the key can't be retrieved it returns the specified default value (in this case a '0').

How to update value for a given key in HashMap - Java 8 getOrDefault() example



Java Program to update a key value in HashMap

Here is our complete Java program to update a value for given key in HashMap in both Java 8 and before. The Java 8 way is more easy and clean but if you are not running on Java 

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

/*
 * Java Program to remove key value pair from Map while 
 * iteration. 
 */
public class Demo {

    public static void main(String[] args) throws Exception {

        Map < String, Integer > wordCount = new HashMap < String, Integer > ();
        wordCount.put("Java", 0);

        wordCount.put("Java", wordCount.get("Java") + 1);

        System.out.println("map before update: " + wordCount);

        // simple way to update value for a given key in HashMap
        if (wordCount.containsKey("Java")) {
            wordCount.put("Java", wordCount.get("Java") + 1);
        } else {
            wordCount.put("Java", 0);
        }

        System.out.println("map after update: " + wordCount);


        // things got better in Java 8 with new getOrDefault() method
        // which return default value if key doesn't exists
        wordCount.put("Java", wordCount.getOrDefault("Java", 0) + 1);

        System.out.println("map after update in Java 8: " + wordCount);
    }

}
Output

map before update: {Java=1}
map after update: {Java=2}
map after update in Java 8: {Java=3}

That's all about how to update values in HashMap in Java. As I said, In order to update, you must first check if key exists and then get the value to avoid NullPointerExceptoin. The same put() method is used to both insert and update key value pair in HashMap.

From Java 8 onwards, using getOrDefault(key) instead of get(key) is better choice as you don't need to check if a key exists in map or not. This method return a default value as opposed to null which makes it safer to use. 

If you want to learn more about such useful changes in Java 8 See Java SE 8 for Really Impatient, one of my favorite book for Java 8. 

Other Java HashMap tutorials you may like to explore:
  • How does get() method of HashMap work in Java? (answer)
  • Difference between ArrayList and HashMap? (difference)
  • 3 ways to loop over a Map in Java? (example)
  • HashSet vs HashMap in Java? (answer)
  • How HashSet internally works in Java? (answer)
  • HashMap vs LinkedHashMap in Java? (answer)
  • ArrayList vs HashMap in Java? (answer)
  • Difference between ConcurrentHashMap and HashMap in Java? (answer)
  • How to sort the HashMap on keys and values in Java? (solution)
  • How ConcurrentHashMap internally works in Java? (answer)
  • HashMap vs ConcurrentHashMap in Java? (answer)
  • The best way to iterate over HashMap in Java? (answer)
  • Difference between HashMap vs Hashtable in Java? (answer)
  • How to convert Map to List in Java? (solution)

Thanks for reading this article so far. If you like this example then please share with your friends and colleagues.

1 comment: