Question
HashMap vs Hashtable in Java: Differences, Performance, and When to Use Each
Question
In Java, what are the differences between HashMap and Hashtable?
Which one is more efficient for applications that do not use multiple threads?
Short Answer
By the end of this page, you will understand how HashMap and Hashtable differ in Java, especially in terms of thread safety, performance, null handling, and typical usage. You will also know why HashMap is usually the better choice for non-threaded applications and what developers use instead of Hashtable in modern Java code.
Concept
HashMap and Hashtable are both Java classes used to store data as key-value pairs.
That means you can store a value and look it up later using a key:
Map<String, Integer> ages = new HashMap<>();
ages.put("Alice", 30);
Both classes are based on hash table data structures, so they are designed for fast lookup, insertion, and deletion.
Core differences
1. Thread safety
Hashtableis synchronized.HashMapis not synchronized.
This means Hashtable tries to make its methods safe when accessed by multiple threads at the same time. HashMap does not do that by default.
2. Performance
Because Hashtable synchronizes its methods, it usually has more overhead.
For non-threaded applications, HashMap is generally more efficient and faster.
3. Null keys and values
- allows:
Mental Model
Think of a map as a labeled cabinet of drawers:
- The key is the label on the drawer.
- The value is what is stored inside.
Now imagine two versions of that cabinet:
HashMap: a normal cabinet that is quick to use, but two people opening and changing drawers at the same time may cause problems.Hashtable: a cabinet with a lock on nearly every action, making it safer for shared use, but slower because of the extra locking.
For one person using the cabinet alone, the locking adds unnecessary delay. That is why HashMap is usually better for non-threaded programs.
Syntax and Examples
Basic syntax
Using HashMap
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
System.out.println(scores.get("Alice"));
Using Hashtable
import java.util.Hashtable;
import java.util.Map;
Map<String, Integer> scores = new Hashtable<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
System.out.println(scores.get("Alice"));
Both examples store and retrieve key-value pairs in a similar way.
Example showing a practical difference
import java.util.HashMap;
import java.util.Hashtable;
public class Main {
public static void {
HashMap<String, String> hashMap = <>();
hashMap.put(, );
hashMap.put(, );
System.out.println(hashMap);
Hashtable<String, String> hashtable = <>();
}
}
Step by Step Execution
Consider this example:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> inventory = new HashMap<>();
inventory.put("Pen", 10);
inventory.put("Book", 5);
inventory.put("Pen", 12);
System.out.println(inventory.get("Pen"));
System.out.println(inventory.get("Book"));
}
}
Step by step
1. Create the map
Map<String, Integer> inventory = new HashMap<>();
A new empty HashMap is created.
2. Add first entry
inventory.put("Pen", 10);
The key "Pen" is stored with the value .
Real World Use Cases
HashMap and similar map structures are used everywhere in Java applications.
Common real uses
Configuration storage
Map<String, String> config = new HashMap<>();
config.put("host", "localhost");
config.put("port", "8080");
Useful for application settings.
Counting values
Map<String, Integer> wordCount = new HashMap<>();
wordCount.put("java", 3);
Useful for text processing, analytics, and reporting.
Caching lookups
A program may cache expensive results using a key so it can reuse them later.
Mapping IDs to objects
Map<Integer, String> users = new HashMap<>();
users.put(101, "Alice");
Useful in APIs, services, and in-memory data stores.
Fast lookup tables
Maps are often used when you need quick access to data by key rather than looping through a list.
Where might appear
Real Codebase Usage
In real Java codebases, developers rarely choose Hashtable for new code.
Common modern patterns
1. Default to Map + HashMap
Map<String, String> headers = new HashMap<>();
This keeps code flexible and easy to refactor.
2. Use guard checks before reading values
if (headers.containsKey("Authorization")) {
System.out.println(headers.get("Authorization"));
}
This helps avoid mistakes when keys may be missing.
3. Use maps for validation and lookup rules
Map<String, Boolean> featureFlags = new HashMap<>();
featureFlags.put("newDashboard", true);
Useful for configuration and feature toggles.
4. Use getOrDefault
int count = wordCounts.getOrDefault(, );
Common Mistakes
1. Assuming Hashtable is always better because it is thread-safe
Being synchronized does not automatically make it the best choice.
For single-threaded programs, Hashtable usually adds unnecessary overhead.
2. Forgetting that Hashtable does not allow null
Broken example:
Hashtable<String, String> table = new Hashtable<>();
table.put(null, "value");
This throws a NullPointerException.
3. Thinking HashMap is safe for concurrent writes
Broken idea:
Map<String, Integer> map = new HashMap<>();
This is fine in one thread, but unsafe if many threads modify it without protection.
To avoid problems in concurrent code, use:
ConcurrentHashMap- external synchronization
4. Using the concrete class type everywhere
Less flexible:
Comparisons
| Feature | HashMap | Hashtable |
|---|---|---|
| Thread-safe by default | No | Yes |
| Synchronized methods | No | Yes |
Allows null key | Yes, one | No |
Allows null values | Yes | No |
| Performance in single-threaded code | Usually faster | Usually slower |
| Legacy class | No | Yes |
| Common in modern Java | Yes | Rarely |
| Better modern concurrent alternative | ConcurrentHashMap |
Cheat Sheet
Map<String, Integer> map = new HashMap<>();
Map<String, Integer> table = new Hashtable<>();
Key rules
HashMapis not synchronized.Hashtableis synchronized.HashMapallows:- one
nullkey - multiple
nullvalues
- one
Hashtableallows:- no
nullkeys - no
nullvalues
- no
- For non-threaded applications,
HashMapis usually faster. Hashtableis a legacy class.- For thread-safe modern code, prefer
ConcurrentHashMap.
Common operations
map.put("A", 1);
map.get("A");
map.containsKey();
map.remove();
map.getOrDefault(, );
FAQ
Is HashMap faster than Hashtable in Java?
Yes, in most single-threaded cases HashMap is faster because it does not synchronize every method.
Why is Hashtable considered legacy?
It comes from older Java APIs and has mostly been replaced by better choices such as HashMap and ConcurrentHashMap.
Should I use Hashtable in new Java code?
Usually no. Use HashMap for normal use and ConcurrentHashMap when you need thread safety.
Can HashMap store null keys and values?
Yes. It allows one null key and multiple null values.
Can Hashtable store null keys or null values?
No. It throws NullPointerException if you try.
What should I use in a multi-threaded Java application?
In most cases, use ConcurrentHashMap instead of .
Mini Project
Description
Build a small Java program that stores product stock levels using a map. This project demonstrates why HashMap is a practical default for single-threaded applications and helps you practice basic map operations such as put, get, containsKey, and getOrDefault.
Goal
Create a simple inventory tracker that stores item names and quantities using HashMap.
Requirements
[ "Create a map that stores product names as keys and stock quantities as values.", "Add at least three products to the inventory.", "Update the quantity of an existing product.", "Print the quantity of a product by its name.", "Print a default value when a product does not exist." ]