What are the differences between a HashMap and a Hashtable in Java?

What are the differences between a HashMap and a Hashtable in Java?

Which is more efficient for non-threaded applications?


There are several differences between HashMap and Hashtable in Java:

  1. Hashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.

  2. Hashtable does not allow null keys or values. HashMap allows one null key and any number of null values.

  3. One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for a LinkedHashMap. This wouldn't be as easy if you were using Hashtable.

Since synchronization is not an issue for you, I'd recommend HashMap. If synchronization becomes an issue, you may also look at ConcurrentHashMap.


Note, that a lot of the answers state that Hashtable is synchronized. In practice this buys you very little. The synchronization is on the accessor/mutator methods will stop two threads adding or removing from the map concurrently, but in the real world, you will often need additional synchronization.

A very common idiom is to "check then put" — i.e. look for an entry in the Map, and add it if it does not already exist. This is not in any way an atomic operation whether you use Hashtable or HashMap.

An equivalently synchronised HashMap can be obtained by:

Collections.synchronizedMap(myMap);

But to correctly implement this logic you need additional synchronisation of the form:

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

Even iterating over a Hashtable's entries (or a HashMap obtained by Collections.synchronizedMap) is not thread-safe unless you also guard the Map against being modified through additional synchronization.

Implementations of the ConcurrentMap interface (for example ConcurrentHashMap) solve some of this by including thread safe check-then-act semantics such as:

ConcurrentMap.putIfAbsent(key, value);