Question 25 · Section 10

Can HashMap Store a null Value?

get(key) returns null in two cases:

Language versions: English Russian Ukrainian

🟢 Junior Level

Yes, HashMap allows storing any number of null values.

Example:

HashMap<String, String> map = new HashMap<>();
map.put("name", null);
map.put("email", null);
map.put("age", "25");

System.out.println(map.get("name")); // null
System.out.println(map.size());      // 3 (all three elements stored)

Problem: When get(key) returns null, it’s unclear — is the key absent or is the value null?

Solution: Use containsKey() to check:

if (map.containsKey("name")) {
    // Key exists, and its value may be null
}

🟡 Middle Level

The Ambiguity Problem

get(key) returns null in two cases:

  1. The key is absent from the map
  2. The key exists, but its value = null
Map<String, String> map = new HashMap<>();
map.put("key", null);

System.out.println(map.get("key"));      // null (value)
System.out.println(map.get("missing"));  // null (no key)
// How to tell them apart?

System.out.println(map.containsKey("key"));      // true
System.out.println(map.containsKey("missing"));  // false

Collection Comparison

Collection Null value Notes
HashMap Allowed Standard behavior
Hashtable Forbidden (NPE) Deprecated
ConcurrentHashMap Forbidden (NPE) Multi-threaded safety
TreeMap Allowed Sorted by keys

Why Does ConcurrentHashMap Forbid Null?

In a multi-threaded environment, you can’t atomically check get() + containsKey():

// Thread A:
String val = map.get(key);     // null
// Thread B removes the key between calls:
// Thread A:
boolean exists = map.containsKey(key); // false — but val was already null!

Best Practices

  1. Avoid null values — use Optional or Null Object
  2. Always check containsKey() before processing null
  3. Document — whether your method can return null from a Map

Common Mistakes

  1. NPE when using the value:
    map.get("key").toString(); // NPE if value = null
    
  2. Confusion with absent key — logical error

🔴 Senior Level

Liveness Problem

In ConcurrentHashMap, banning null eliminates ambiguity in check-then-act:

// Hypothetical scenario (CHM actually forbids null)
// Shows WHY CHM forbids null:
if (map.get(key) == null) {        // Step 1: null
    if (!map.containsKey(key)) {   // Step 2: false (key added by another thread!)
        map.put(key, value);       // Step 3: overwrites someone else's value
    }
}

Banning null makes get() == null an unambiguous indicator of key absence.

Internal Implementation

In HashMap, null value is stored as a regular entry:

// putVal:
Node<K,V> e;
// ...
e.value = value; // value can be null

The value doesn’t participate in hashing — no restrictions.

Optional as an Alternative

Map<String, Optional<Value>> map = new HashMap<>();

// Explicit intent:
map.put("key", Optional.empty());  // Intentionally "nothing"
map.put("key", Optional.of(val));  // Has a value

// Retrieval:
Optional<Value> opt = map.getOrDefault("key", Optional.empty());

Overhead: an additional Optional object per entry.

Null Object Pattern

class User {
    static final User EMPTY = new User("", 0);
    // ...
}

Map<String, User> map = new HashMap<>();
map.put("missing", User.EMPTY); // Instead of null

Zero overhead, explicit semantics, NPE-safe.

Memory Implications

A null value doesn’t consume additional memory:

  • Reference to null = 0 bytes (just absence of an object)
  • Node is still created (header + hash + key + value ref + next)

Production Diagnostics

Signs of null-value problems:

  • NPE in chain methods: map.get(key).method()
  • Logical error: null interpreted as “no data”
  • In DB: null values in Map → null in column (may violate constraint)

🎯 Interview Cheat Sheet

Must know:

  • HashMap allows any number of null values
  • Problem: get(key) = null is ambiguous — key absent OR value = null?
  • Solution: containsKey() for unambiguous check
  • ConcurrentHashMap forbids null values — to eliminate ambiguity in check-then-act
  • Null Object Pattern: create an EMPTY constant instead of null
  • Optional as alternative: Map<String, Optional> — explicit intent

Common follow-up questions:

  • Why does CHM forbid null values? — Liveness Problem: get=null must unambiguously mean “no key” for atomic operations
  • How to tell null from absent key? — containsKey()
  • How does null value differ from null key? — many null values allowed, only one null key
  • Optional vs Null Object? — Optional = additional object (overhead), Null Object = zero overhead

Red flags (DO NOT say):

  • “HashMap forbids null values” — it allows them
  • “ConcurrentHashMap allows null values” — no, NPE
  • “null value = 0 bytes” — Node is still created (~32-48 bytes)

Related topics:

  • [[24. Can HashMap Store a null Key]]
  • [[23. What is ConcurrentHashMap and How Does It Differ from HashMap]]