Why HashMap Allows One Null Key While Hashtable Doesn’t?
1. Background
Hashtable
Introduced in Java 1.0 (before collections framework).
It’s synchronized, which means it’s thread-safe.
Designed at a time when nulls were considered programming errors (especially in multithreaded contexts).
Therefore, it doesn’t allow null keys or values.
HashMap
Introduced later in Java 1.2 as part of the Collections Framework.
It’s not synchronized (faster, but not thread-safe).
Designed to be more flexible, including allowing one null key and multiple null values.
2. Internal Working Difference
Let’s look at how key lookup works in both:
In HashMap
When you insert a key-value pair, HashMap calls: int hash = (key == null) ? 0 : key.hashCode(); So, if the key is null, it assigns a default hash value (0).
This means all null keys go into bucket index 0.
When retrieving a null key, HashMap simply checks: if (key == null) return getForNullKey(); and fetches the value stored in bucket 0.
In Hashtable
It directly calls key.hashCode() without a null check. int hash = key.hashCode(); // Throws NullPointerException if key is null
So, inserting a null key will immediately throw NullPointerException.
This behavior is intentional to prevent confusion or concurrency bugs in older thread-safe code.
3. Design Rationale
Aspect
HashMap
Hashtable
Introduced in
Java 1.2 (Collections Framework)
Java 1.0 (Legacy class)
Synchronization
Non-synchronized
Synchronized
Null keys
Allowed (one null key)
Not allowed
Null values
Allowed
Not allowed
Performance
Faster (no synchronization overhead)
Slower (synchronized methods)
Thread safety
Not thread-safe
Thread-safe (synchronized)
Why HashMap allows one null key:
Flexibility: Collections Framework promotes ease of use.
Consistency: Many data structures (like lists, sets) allow null elements.
Utility: Useful for representing a “default” or “missing” key explicitly.
Controlled behavior: Internally handled via bucket index 0.
Why Hashtable disallows null keys:
Historical reason: Designed before Java Collections existed.
Thread-safety concern: In synchronized code, a null check might race with another thread inserting/removing entries, leading to subtle bugs.
Error prevention: Null keys often indicate logic errors in legacy systems.