Can HashMap Store a null Value?
get(key) returns null in two cases:
🟢 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:
- The key is absent from the map
- 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
- Avoid null values — use Optional or Null Object
- Always check
containsKey()before processing null - Document — whether your method can return null from a Map
Common Mistakes
- NPE when using the value:
map.get("key").toString(); // NPE if value = null - 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]]