collections

HashMap vs Hashtable

šŸ”¹ HashMap vs Hashtable (Deep Dive, Interview-Ready)

Both HashMap and Hashtable implement the Map interface and store key-value pairs using a hash table data structure. However, just like ArrayList and Vector, they represent a modern vs. legacy design divide, specifically regarding thread safety and null handling.


šŸ“Œ 1. Core Difference (One-Liner)

Hashtable is a legacy, synchronized class that does not allow nulls, while HashMap is a modern, unsynchronized class that allows one null key and multiple null values.


šŸ“Š 2. Detailed Comparison

FeatureHashMapHashtable
SynchronizationNot synchronizedFully synchronized (every method)
Thread SafetyThread-safe by default? NoThread-safe by default? Yes
PerformanceFasterSlower (locking overhead)
Null KeyAllowed (Maximum 1)Not allowed (Throws NullPointerException)
Null ValuesAllowed (Multiple)Not allowed (Throws NullPointerException)
Legacy StatusModern (Java 1.2 Collections Framework)Legacy class (Java 1.0, retrofitted)
Traversal MethodIteratorEnumerator + Iterator
Fail-Fast BehaviorIterators are fail-fastEnumerator is NOT fail-fast
Usage TodayDefault choice for mapsObsolete / Rare

šŸ“Œ 3. Internal Working Differences

šŸ”ø HashMap

Internal Storage:

transient Node<K,V>[] table;

How it handles Nulls: HashMap has a special check for null keys. It routes the null key to index 0 of the internal array without trying to call .hashCode() on it.

// Inside HashMap's hash function: static final int hash(Object key) { return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }

šŸ‘‰ Optimized for: Speed in single-threaded environments.


šŸ”ø Hashtable

Internal Storage:

private transient Entry<?,?>[] table;

How it handles Nulls: Hashtable blindly calls .hashCode() on the provided key and .equals() on the value. If either is null, it instantly throws a NullPointerException.

// Inside Hashtable's put method: if (value == null) { throw new NullPointerException(); } int hash = key.hashCode(); // Throws NPE if key is null

šŸ‘‰ Impact: Strict non-null enforcement.


šŸ“Œ 4. Synchronization Details (Very Important)

šŸ”ø Hashtable

Every core method in Hashtable is synchronized at the method level:

public synchronized V put(K key, V value) { ... } public synchronized V get(Object key) { ... }

šŸ‘‰ The Problem: The lock is applied on the entire Hashtable object (this). If Thread A is doing a put(), Thread B cannot even do a get(). This causes severe bottlenecks in highly concurrent applications.


šŸ”ø HashMap

Contains no synchronization.

āœ… How to make HashMap thread-safe?

If you need a thread-safe map, do not use Hashtable. Instead, use:

1. ConcurrentHashMap (Best Practice)

  • Uses fine-grained locking (locks only a portion/bucket of the map).
  • Allows multiple threads to read and write simultaneously.
Map<String, String> map = new ConcurrentHashMap<>();

2. Collections.synchronizedMap (If legacy required)

  • Creates a synchronized wrapper around a HashMap.
  • Similar performance issue as Hashtable (object-level lock), but allows nulls.
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());

šŸ“Œ 5. Fail-Fast vs Non Fail-Fast

šŸ”ø HashMap Iterator

  • Fail-fast.
  • Uses an internal modCount to track structural changes. If modCount changes while an iterator is traversing, it throws ConcurrentModificationException.

šŸ”ø Hashtable Enumerator

  • Not fail-fast.
  • Hashtable.elements() returns an Enumeration. If the Hashtable changes during traversal, the Enumeration does not throw an exception (though it might return inconsistent results).

šŸ”„ Interview Gold Statement

"Hashtable is a legacy, fully synchronized map that does not allow nulls and locks the entire object for every operation, causing poor performance. HashMap is the modern, unsynchronized standard that allows nulls and is highly optimized. For thread-safe mapping today, we entirely avoid Hashtable and instead use ConcurrentHashMap, which provides lock-striping for vastly superior concurrent performance."


⚔ Final Verdict

  • āœ… Use HashMap in single-threaded environments.
  • āœ… Use ConcurrentHashMap in multi-threaded environments.
  • āŒ Never use Hashtable in modern Java code.
HashMap vs Hashtable | DevExCode