Java HashMap vs Hashtable
0 CommentsLast Updated on October 19, 2024 by jt
In Java, the HashMap and HashTable are both data structures that store data in key value pairs. When you store data in these, the key value is hashed, then is used as an index for fast access to the stored data.
HashMap vs Hashtable
| HashMap | Hashtable |
| Introduced in Java 1.2 | Introduced in Java 1.0, considered obsolete with the addition of HashMap in Java 1.2 |
| Not synchronized, not thread-safe | Synchronized, thread-safe |
| Faster because it is not synchronized | Slower due to synchronization overhead |
| Will allow one null key, and null values | Will not allow null keys or null values |
Extends AbstractMap and implements Map interface | Extends Dictionary, implements Map Interface |
Some other key differences are:
- Because of synchronization and thread safety,
Hashtableis much slower thanHashMapif used in single threaded environment. HashMapallows onenullkey and multiplenullvalues whereasHashtabledoesn’t allownullvalues.HashMapis traversed byIteratorwhileHashtablecan be traversed by bothIteratorand the legacyEnumeration.IteratorinHashMapis a fail-fast iterator. It throwsConcurrentModificationExceptionif any thread other than the iterator’sremove()method tries to modify the map structurally. Thus, in the face of concurrent modification, the iterator fails fast and cleanly, rather than risking undesirable behaviour. However, TheEnumerationreturned byHashtabledoesn’t have this behaviour.
In addition to these differences, one commonly asked question is Why HashMap stores one null key but Hashtable does not?
HashMap, allows storing one null key and multiple null values. The reason for allowing only one null key is because keys in a HashMap has to be unique. On the other hand Hashtable does not allow null keys. This is because the objects used as keys in a Hashtable implements the hashCode() and equals() methods for their storage and retrieval. Since null is not an object it cannot implement the methods. If you try hashing a null key, it will throw a NullPointerException.
Synchronization with Hashtable
While Hashtable does have built-in synchronization, it may not be enough to ensure complete thread safety. This is because the synchronization is applied at the method level.
For example you might check if a key exists with containsKey() before a put() operation. Another thread could add the key between method calls, leading to an unexpected exception.
To avoid these inherit limitations of Hashtable, you might wish to consider using Java’s ConcurrentHashMap. Introduced in Java 1.5, the ConcurrentHashMap is thread-safe and performant.
HashMap Example Usage
The following example shows how HashMap will accept values and null values for keys and values.
@Test
void hashMapTest() {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(null, "test");
hashMap.put("test", null);
hashMap.put("key1", "test");
hashMap.put("key2", "test2");
hashMap.forEach((k, v) -> System.out.println("Key: " + k + " Value: " + v));
}Following is the output from the above test.
Key: null Value: test
Key: key1 Value: test
Key: key2 Value: test2
Key: test Value: nullHashTable Example Useage
The following test shows an example shows an example of using Hashtable.
@Test
void hashTableTest() {
Hashtable<String, String> hashTable = new Hashtable<>();
hashTable.put("key1", "test");
hashTable.put("key2", "test2");
hashTable.put("key3", "test2");
hashTable.forEach((k, v) -> System.out.println("Key: " + k + " Value: " + v));
}This will generate the following output:
Key: key1 Value: test
Key: key2 Value: test2
Key: key3 Value: test2Null Values with HashTable
The following test tries to set a null key with Hashtable.
@Test
void hashTableWithNullKeyTest() {
Hashtable<String, String> hashTable = new Hashtable<>();
hashTable.put("key1", "test");
hashTable.put("key2", "test2");
hashTable.put(null, "test2");
hashTable.forEach((k, v) -> System.out.println("Key: " + k + " Value: " + v));
}
java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "key" is null
at java.base/java.util.Hashtable.put(Hashtable.java:481)
at guru.springframework.HashMapvsHashtable.hashTableWithNullKeyTest(HashMapvsHashtable.java:39)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) The following test tries to set a null value with Hashtable.
@Test
void hashTableWithNullValueTest() {
Hashtable<String, String> hashTable = new Hashtable<>();
hashTable.put("key1", "test");
hashTable.put("key2", "test2");
hashTable.put("key3", null);
hashTable.forEach((k, v) -> System.out.println("Key: " + k + " Value: " + v));
}
java.lang.NullPointerException
at java.base/java.util.Hashtable.put(Hashtable.java:476)
at guru.springframework.HashMapvsHashtable.hashTableWithNullValueTest(HashMapvsHashtable.java:49)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)Which to Use? HashMap or Hashtable?
If thread-safety is not a concern, HashMap is the clear choice. Its faster and uses less memory than Hashtable.
When thread-safety is a concern, you should consider using ConcurrentHashMap rather than Hashtable.
As of Java 21, Hashtable has not been deprecated, but it is considered obsolete by the Java community.
The source code examples used in this post are available in my GitHub repository here.
