HashMap vs Hashtable in Java: Differences and Internal Structure

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

HashMap vs Hashtable in Java: Who Wins? Let's Look Under the Hood

\n\n

If you've ever wondered, "What exactly is the difference between HashMap and Hashtable?" — you're not alone. This is one of the most popular questions on Stack Overflow, and for good reason. Both classes store data in key-value format, both use hashing, but they live in different worlds. One is fast and modern, the other is old, reliable, but a bit clunky. Let's look under the hood and figure out what's what.

\n\n

In this article, we won't just list the differences. We'll understand how the internal mechanics work, why one class allows null and the other doesn't, and when to use ConcurrentHashMap instead of both.

\n\n

A Brief History Lesson

\n\n

Hashtable appeared in Java back in version 1.0. It was one of the first collection classes, and it was synchronized from the start. In those days, multithreading was rare, but Java developers decided to play it safe. Later, in Java 2 (1.2), new collections from the Collections Framework were released, including HashMap. It was unsynchronized but much faster. Since then, Hashtable has been considered legacy, although it hasn't been removed from the language.

\n\n

The Main Difference: Synchronization and Threads

\n\n

The first and most important difference is synchronization. Hashtable methods (e.g., put(), get(), remove()) are marked with the synchronized keyword. This means two threads cannot execute the same method on the same Hashtable object simultaneously. That sounds like an advantage, but in practice, it becomes a bottleneck.

\n\n
// Hashtable — all methods are synchronized\nHashtable<String, String> table = new Hashtable<>();\ntable.put("key1", "value1"); // thread-safe, but slow under high contention\n\n// HashMap — not synchronized\nHashMap<String, String> map = new HashMap<>();\nmap.put("key1", "value1"); // fast, but not thread-safe\n
\n\n

If you're working in a single-threaded application (which most are), HashMap will be faster because it doesn't waste time acquiring and releasing locks. If you need thread safety, it's better not to use Hashtable, but instead use ConcurrentHashMap (introduced in Java 5). It uses finer-grained locking (segments or bucket-level locks) and performs significantly better in a multithreaded environment.

\n\n

Null, Null, and More Null

\n\n

The second important difference is handling null. HashMap allows null both as a key (exactly once) and as values (any number of times). Hashtable, on the other hand, will throw a NullPointerException if you try to pass null.

\n\n
HashMap<String, String> map = new HashMap<>();\nmap.put(null, "nullKey"); // OK\nmap.put("key", null);     // OK\nSystem.out.println(map.get(null)); // "nullKey"\n\nHashtable<String, String> table = new Hashtable<>();\n// table.put(null, "value"); // NullPointerException!\n// table.put("key", null);   // NullPointerException!\n
\n\n

Why is that? It all comes down to how hashing works. In HashMap, a special hash code of 0 is used for the null key, and it is placed in the zero bucket. Hashtable, however, uses an older mechanism where calling hashCode() on null causes an error. Additionally, Hashtable does not account for null values, as that would break the logic of synchronized operations.

\n\n

Internal Structure: How a Hash Table Works Under the Hood

\n\n

To understand the difference more deeply, let's look inside. Both HashMap and Hashtable are based on a hash table. This is an array of "buckets," where each bucket is a linked list (or a tree, starting from Java 8). When you add a

Blogs

Book Recommendations