Java – How to update the value of a key in HashMap
This article shows a few ways to update or increase a value of a key in a HashMap.
Table of contents
- 1. Update the value of a key in HashMap
- 2. Increase the value of a key in HashMap
- 3. Java 8 getOrDefault()
- 4. Java 8 compute and merge
- 5. Java 8 computeIfPresent
- 6. Java 8 computeIfAbsent and putIfAbsent
- 7. References
1. Update the value of a key in HashMap
If the key doesn’t exist, the put
method creates the key with the associated value; If the key exists, the put
updates its value.
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
System.out.println(map.get("a")); // 1
map.put("a", 2); // key `a` exists, update or replace the value
System.out.println(map.get("a")); // 2
Output
1
2
2. Increase the value of a key in HashMap
2.1 We can update or increase the value of a key with the below get() + 1
method.
Map<String, Integer> map = new HashMap<>();
// if key doesn't exist, throws NullPointerException
map.put("count", map.get("count") + 1);
Output
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "java.lang.Integer.intValue()"
because the return value of "java.util.Map.get(Object)" is null
2.2 However, the above method will throw a NullPointerException
if the key doesn’t exist. The fixed is uses the containsKey()
to ensure the key exists before update the key’s value.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
if (map.containsKey("count")) {
map.put("count", map.get("count") + 1);
} else {
map.put("count", 1);
}
}
System.out.println(map.get("count"));
Output
10
Or one liner like the below method.
map.put("count", map.containsKey("count") ? map.get("count") + 1 : 1);
3. Java 8 getOrDefault()
In Java 8, we can use getOrDefault
to provide a default value for a non-exists key.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// if key "count" doesn't exist, default to 0
map.put("count", map.getOrDefault("count", 0) + 1);
}
System.out.println(map.get("count"));
Output
10
4. Java 8 compute and merge
Java 8 also added compute()
and merge()
to enhance the Map
interface. The below examples increase the value of a key in HashMap
.
Further Reading
Most of the new Java 8 Map APIs accept either a Function
and a BiFunction
as the argument, ensure you understand the concept of the following function interfaces:
4.1 Java 8 merge example
For merge()
, the first argument is the Map’s key, the second argument is the default value, the third argument is a BiFunction
to accept two arguments and provide an output for the key.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// if key doesn't exist, default to 1
// lambda
map.merge("count", 1, (v1, v2) -> v1 + v2);
}
System.out.println(map.get("count"));
Output
10
We can simplify the lambda with method reference.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.merge("count", 1, Integer::sum);
}
System.out.println(map.get("count"));
4.2 Java 8 compute
This compute
is similar to the merge
; the first argument is the Map’s key, and the second argument is a BiFunction
.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.compute("count", (k, v) -> (v == null) ? 1 : v + 1);
}
System.out.println(map.get("count"));
Output
10
Yet another Java 8 compute
example to increase the key’s value.
package com.mkyong.basic;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// lambda
//map.compute("count", (k, v) -> createDefault(k, v));
// method reference
map.compute("count", TestMap::createDefault);
}
System.out.println(map.get("count"));
}
private static Integer createDefault(String key, Integer value) {
if (value == null) {
return 1;
}
return value + 1;
}
}
Output
10
5. Java 8 computeIfPresent
The computeIfPresent
is similar to the compute
but runs the compute method only if the key is present or exists.
5.1 The below computeIfPresent
example will print a null
.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// key count not exists, skip x 10
map.computeIfPresent("count", (k,v) -> v + 1);
}
System.out.println(map.get("count"));
Output
null
5.2 The below computeIfPresent
example will print a 10
.
Map<String, Integer> map = new HashMap<>();
map.put("count", 0);
for (int i = 0; i < 10; i++) {
// key exists, ok, run this
map.computeIfPresent("count", (k, v) -> v + 1);
}
System.out.println(map.get("count"));
Output
10
6. Java 8 computeIfAbsent and putIfAbsent
6.1 The computeIfAbsent
is similar to the computeIfPresent
, but runs the compute method only if the key is NOT present or exists.
package com.mkyong.basic;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// run once only, if key doesn't exists, else skip this.
map.computeIfAbsent("count", TestMap::createDefault);
}
System.out.println(map.get("count"));
}
private static Integer createDefault(String key) {
System.out.println("Creating Default....");
if ("count".equalsIgnoreCase(key)) {
return 0;
} else {
return -1;
}
}
}
Output
Creating Default....
0
6.2 The below example uses computeIfAbsent
to provide a default value for the key; computeIfPresent
to update or increase the key value.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.computeIfAbsent("count", TestMap::createDefault); // default 0
map.computeIfPresent("count", (k, v) -> v + 1); // increase +1
}
System.out.println(map.get("count"));
Output
Creating Default....
10
6.3 There is also a putIfAbsent
to update the value only if the key doesn’t exist.
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
//map.computeIfAbsent("count", TestMap::createDefault);
map.putIfAbsent("count", 0);
map.computeIfPresent("count", (k, v) -> v + 1);
}
System.out.println(map.get("count"));
The difference is computeIfAbsent
uses a Function
to update the value; the putIfAbsent
update the value directly.