Java: Difference between HashMap and Hashtable
HashMap and Hashtable are both key-value data structures in Java, but they differ in synchronization, null handling, and performance. In this article, you will get to know the detailed comparison between HashMap and Hashtable.
1. Synchronization
- HashMap: Not synchronized, meaning it’s not thread-safe. Multiple threads can access and modify a HashMap concurrently without proper synchronization, which can lead to inconsistent data.
- Hashtable: Synchronized, meaning it’s thread-safe. Only one thread can access and modify a Hashtable at a time, which prevents data inconsistency but can slow down performance.
2. Null Values
- HashMap: Allows one null key and multiple null values.
- Hashtable: Does not allow any null keys or values. Attempting to insert a null key or value will throw a
NullPointerException
.
Learn more about: Best practices to avoid NullPointerException in Java
3. Performance
- HashMap: Generally faster because it’s not synchronized, making it more efficient in single-threaded applications.
- Hashtable: Slower due to synchronization overhead.
4. Legacy
- HashMap: Part of the Java Collections Framework and was introduced in Java 1.2.
- Hashtable: A legacy class from the earlier versions of Java (before Java 2), later retrofitted to implement the
Map
interface.
5. Iterator
- HashMap: Uses fail-fast iterator, which throws a
ConcurrentModificationException
if the map is modified after the iterator is created. - Hashtable: Uses an enumerator that does not throw
ConcurrentModificationException
.
Learn more about: ConcurrentModificationException in Java
HMAndHT.java
package org.websparrow;
import java.util.HashMap;
import java.util.Hashtable;
public class HMAndHT {
public static void main(String[] args) {
// HashMap example
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("Apple", 1);
hashMap.put("Banana", 2);
hashMap.put(null, 3); // Allows null key
hashMap.put("Orange", null); // Allows null value
System.out.println("HashMap: " + hashMap);
// Hashtable example
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("Apple", 1);
hashtable.put("Banana", 2);
// hashtable.put(null, 3); // Throws NullPointerException
// hashtable.put("Orange", null); // Throws NullPointerException
System.out.println("Hashtable: " + hashtable);
}
}
When to use HashMap and Hashtable?
- Use HashMap when:
- You do not require thread safety.
- You are working in a single-threaded environment.
- You need to allow null keys or values.
- Use Hashtable when:
- You need thread safety in a multi-threaded environment.
- Synchronization is a requirement.
- You do not need to store null keys or values.
Time Complexity
- HashMap: O(1) for put and get operations, assuming a good hash function and low collision rate.
- Hashtable: Also O(1) for put and get operations under the same conditions.
Underlying Data Structures
Both HashMap and Hashtable are backed by an array of Entry
or Node
objects, which store key-value pairs. These entries are organized into buckets based on the hash code of the keys. When a collision occurs (i.e., two keys have the same hash code), the entries are linked together in a linked list or tree (in HashMap starting from Java 8).