Question 26 · Section 10

What is the Difference Between HashMap and Hashtable?

All methods are synchronized:

Language versions: English Russian Ukrainian

🟢 Junior Level

HashMap and Hashtable — both store data in “key-value” format, but they are very different classes.

HashMap Hashtable
Fast Slow
Not thread-safe Thread-safe
Allows null Forbids null
Modern (Java 1.2) Legacy (Java 1.0)

Example:

// HashMap — modern choice
Map<String, Integer> map = new HashMap<>();
map.put(null, 1);     // OK
map.put("key", null); // OK

// Hashtable — deprecated, don't use
Map<String, Integer> table = new Hashtable<>();
table.put(null, 1);     // NullPointerException!
table.put("key", null); // NullPointerException!

Main advice: Always use HashMap (or ConcurrentHashMap for multi-threading). Hashtable is legacy.

🟡 Middle Level

Detailed Comparison

Characteristic Hashtable HashMap
Synchronization Yes (every method) No
Null keys No (NPE) Yes (1)
Null values No (NPE) Yes (many)
Inheritance Dictionary AbstractMap
Java version JDK 1.0 JDK 1.2
Indexing hash % n (n-1) & hash
Iterator Enumeration + Iterator Iterator (fail-fast)

Why is Hashtable Slow?

All methods are synchronized:

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

Even for reading — a lock is acquired. In a multi-threaded environment, all threads queue up.

Indexing Algorithm

HashMap: (n-1) & hash — fast bitwise mask (requires power of two) Hashtable: (hash & 0x7FFFFFFF) % n — modulo division (slower, but works with any size)

HashMap additionally spreads the hash via a spread function (XOR of high and low 16 bits) for better distribution. Hashtable takes hashCode() directly.

Where Is Hashtable Still Found?

  • Legacy code (projects older than 15-20 years)
  • Interview questions 😊
  • Textbooks that haven’t been updated

What to Use Instead?

Need Use Instead of Hashtable
Simple Map HashMap
Thread safety ConcurrentHashMap
Synchronized Map Collections.synchronizedMap(new HashMap<>())

Common Mistakes

  1. Using Hashtable in new code — this is an anti-pattern
  2. Thinking Hashtable = fast ConcurrentHashMap — no, it’s slower
  3. Enumeration vs Iterator — Hashtable returns Enumeration (no remove, no fail-fast)

🔴 Senior Level

Internal: Synchronization Overhead

Each synchronized method — monitor enter/exit:

// Hashtable.put:
public synchronized V put(K key, V value) {
    // monitor enter
    // ... logic
    // monitor exit
}

In a multi-threaded environment:

  • Contention on a single monitor
  • Thread parking/unparking
  • Memory barrier on every enter/exit

ConcurrentHashMap solves this via CAS + granular locking.

Historical Context

  • Dictionary (1995) — abstract ancestor of Hashtable, deprecated
  • Hashtable (1995) — adapted to Map in Java 1.2
  • HashMap (1998) — created from scratch for Collections Framework

Hashtable was kept only for backward compatibility.

Indexing: Modulo vs Bitwise AND

// Hashtable:
int index = (hash & 0x7FFFFFFF) % table.length;
// & 0x7FFFFFFF — removes the sign bit (hash can be negative)
// % — modulo division, expensive operation

// HashMap:
int index = (n - 1) & hash;
// Only when n = 2^k
// & — bitwise AND, 1 cycle

Hashtable can use prime numbers for table size (better distribution), but modulo is more expensive.

Thread Safety: Hashtable vs ConcurrentHashMap

Metric Hashtable ConcurrentHashMap
Read (1 thread) ~15 ns ~8 ns
Read (8 threads) ~500 ns ~60 ns
Write (1 thread) ~20 ns ~15 ns
Write (8 threads) ~2000 ns ~120 ns

Hashtable loses 10-30x on multi-threaded operations.

Why Hashtable is Still in JDK

  • Backward compatibility (millions of lines of legacy code)
  • Some enterprise frameworks depend on it
  • Removing it would break code (even if it’s bad)

Modern Best Practice

// Never:
Map<K, V> map = new Hashtable<>();

// Instead:
Map<K, V> map = new HashMap<>();                        // Single-thread
Map<K, V> map = new ConcurrentHashMap<>();              // Multi-thread
Map<K, V> map = Collections.synchronizedMap(new HashMap<>()); // If full synchronization needed

🎯 Interview Cheat Sheet

Must know:

  • Hashtable — legacy (Java 1.0), HashMap — modern choice (Java 1.2)
  • Hashtable is synchronized (every method) → slow, HashMap — not
  • Hashtable forbids null, HashMap allows null key and null values
  • Indexing: Hashtable = (hash & 0x7FFFFFFF) % n, HashMap = (n-1) & hash
  • HashMap uses spread function (XOR high/low 16 bits), Hashtable takes hashCode() directly
  • Hashtable loses 10-30x to ConcurrentHashMap on multi-threaded operations
  • Hashtable kept only for backward compatibility

Common follow-up questions:

  • When to use Hashtable? — never in new code; only legacy support
  • Why is Hashtable slower than ConcurrentHashMap? — single monitor for everything vs granular locking + CAS
  • How does Enumeration differ from Iterator? — Enumeration has no remove() and no fail-fast
  • Why is HashMap faster? — bitwise mask & vs division %, no synchronization

Red flags (DO NOT say):

  • “Hashtable = fast thread-safe Map” — no, slower than ConcurrentHashMap
  • “HashMap uses division for indexing” — no, bitwise mask
  • “You can use Hashtable in new code” — no, it’s an anti-pattern

Related topics:

  • [[23. What is ConcurrentHashMap and How Does It Differ from HashMap]]
  • [[22. How HashMap Works in a Multi-threaded Environment]]
  • [[01. How HashMap Works Internally]]