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).

References

  1. Java Map.of() vs Map.ofEntries() Method
  2. How to sort Map by Key or Value in Java 8

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.