liveBook · Manning

Map.compute

As explained in 100 Java Mistakes and How to Avoid Them

Map.compute is a Java Map interface method that recomputes a key's value and removes the mapping when the remapping result is null.

Map.compute recomputes the value associated with a key through a remapping function. A null result removes the mapping, and the method does not distinguish an existing null mapping from an absent key. section 8.4

Null result deletes the entry

var map = new HashMap<String, String>(); map.put("x", null); map.compute("x", (k, v) -> null); System.out.println(map); // {} section 8.4

This makes null a consequential return value rather than an ordinary stored value. Code that intends to preserve an entry must return a non-null value; code that returns null deliberately requests removal. section 8.4

For concurrently updated maps, compute belongs to the Map methods intended to replace non-atomic get-and-put sequences. Use the concurrent map implementation's documented atomic operations rather than reading and writing separately. section 9.12

Avoid these common mistakes:

  • Do not infer that a null value means the key is absent; compute treats both situations alike. section 8.4
  • Do not use a separate get followed by put when another thread can update the same map entry. section 9.12
  • Check whether a null remapping result is an intended deletion before adopting a compute-based update. section 8.4
var map = new HashMap<String, String>();
map.put("x", null);
map.computeIfAbsent("x", k -> null);     #1
System.out.println(map);     #2
map.compute("x", (k, v) -> null);     #3
System.out.println(map);     #4

Compare compute with computeIfAbsent when a null mapping already exists; the example isolates how null results affect the map. section 8.4

Table 8.2 Behavior of java.util.Map interface methods with respect to null
java.util.Map interface method
Distinguishes between existing null mapping and no mapping at all?
Puts null mapping if the value parameter is null?
Removes existing mapping if lambda returns null?
containsKey
yes
—
—
getOrDefault
yes
—
—
get
no
—
—
put
no
yes
—
putIfAbsent
no
yes
—
compute
no
—
yes
computeIfPresent
no
—
yes
computeIfAbsent
no
—
no
merge
no
no
yes

Use the method table to compare compute with get, put, computeIfPresent, computeIfAbsent, and merge across null-handling behaviors. section 8.4

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains null mappings, deletion on null results, related Map methods, and atomic-update use, without detailing implementation internals.
Examples
Uses a HashMap containing a null mapping and contrasts separate concurrent-map get-and-put code with merge.
What it assumes
Assumes familiarity with Java Map operations, remapping functions, null values, and concurrent collections.
What you can do after
Apply it to recompute mappings while recognizing that a null result deletes the entry and separate concurrent accesses are unsafe.
How it connects
Connects Map.compute with null mappings, computeIfAbsent, computeIfPresent, merge, and concurrent collections.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.