Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java computeIfAbsent: null means no new mapping

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

Map.computeIfAbsent calls its mapping function when the key is absent or mapped to null, and stores only a non-null result.

The null case has two meanings

A missing receipt key returns null from the loader, so the map remains without that key. Another key already mapped to null is treated as needing a value; the loader fills it. containsKey reveals the initial null mapping, while get cannot distinguish it from absence.

If a loader can fail, prefer an explicit result or exception over returning null ambiguously. The mapping function should not structurally edit the same map. merge solves a different case: combining a supplied value with an existing one.

Do not infer once-only concurrent loading

This program uses a plain HashMap and no concurrent calls. Loading from a remote service needs a separate cache-stampede, timeout and stale-value policy. A ConcurrentHashMap's computeIfAbsent contract differs from the default Map operation and should be tested under its own boundary.

Working program

Java
import java.util.HashMap;
import java.util.Map;
public class ReceiptLookupCache {
    public static void main(String[] args) {
        Map<String, String> receiptState = new HashMap<>();
        receiptState.put("R-41", null);
        System.out.println("present-null=" + receiptState.containsKey("R-41"));
        System.out.println("missing=" + receiptState.computeIfAbsent("R-99", id -> null));
        System.out.println("stored-missing=" + receiptState.containsKey("R-99"));
        System.out.println("loaded=" + receiptState.computeIfAbsent("R-41", id -> "reviewed"));
    }
}

Output

Output
present-null=true
missing=null
stored-missing=false
loaded=reviewed

Costs and boundaries

Expected HashMap lookup cost depends on hash distribution. A mapping function may do arbitrary work, so do not report the whole operation as constant time without including that work. This fixture does not test concurrent loading.

Common Mistakes

  • Do not use get == null when presence matters.
  • Do not assume a null loader result is cached.
  • Do not infer a cross-thread single-loader guarantee from a plain Map example.

Read next

Java HashMap: keys, collisions, and update operations, Java Map.merge: combine a value or remove its mapping, Java ConcurrentHashMap: atomic updates and weakly consistent reads, Spring cache keys: separate tenants and test the loader count.

java
collections
map-compute-if-absent-null
Storage details