Java HashMap vs Hashtable

Java HashMap vs Hashtable

0 Comments

Last 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

HashMapHashtable
Introduced in Java 1.2Introduced in Java 1.0, considered obsolete with the addition of HashMap in Java 1.2
Not synchronized, not thread-safeSynchronized, thread-safe
Faster because it is not synchronizedSlower due to synchronization overhead
Will allow one null key, and null valuesWill not allow null keys or null values
Extends AbstractMap and implements Map interfaceExtends Dictionary, implements Map Interface
HashMap vs Hashtable

Some other key differences are:

  • Because of synchronization and thread safety, Hashtable is much slower than HashMap if used in single threaded environment.
  • HashMap allows one null key and multiple null values whereas Hashtable doesn’t allow null values.
  • HashMap is traversed by Iterator while Hashtable can be traversed by both Iterator and the legacy Enumeration.
  • Iterator in HashMap is a fail-fast iterator. It throws ConcurrentModificationException if any thread other than the iterator’s remove() 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, The Enumeration returned by Hashtable doesn’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: null

HashTable 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: test2

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

About jt

    You May Also Like

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.