What are the differences between a HashMap and a Hashtable in Java?
What are the differences between a HashMap and a Hashtable in Java?
Accepted Answer
There are several differences between HashMap
and Hashtable
in Java:
Hashtable
is synchronized, whereasHashMap
is not. This makesHashMap
better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.Hashtable
does not allownull
keys or values.HashMap
allows onenull
key and any number ofnull
values.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 theHashMap
for aLinkedHashMap
. This wouldn't be as easy if you were usingHashtable
.
Since synchronization is not an issue for you, I'd recommend HashMap
. If synchronization becomes an issue, you may also look at ConcurrentHashMap
.
Read more… Read less…
Note, that a lot of the answers state that Hashtable is synchronised. 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 synchronisation.
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
from 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);
Hashtable
is considered legacy code. There's nothing about Hashtable
that can't be done using HashMap
or derivations of HashMap
, so for new code, I don't see any justification for going back to Hashtable
.
This question is often asked in interview to check whether candidate understands correct usage of collection classes and is aware of alternative solutions available.
- The
HashMap
class is roughly equivalent toHashtable
, except that it is non synchronized and permits nulls. (HashMap
allows null values as key and value whereasHashtable
doesn't allownull
s). HashMap
does not guarantee that the order of the map will remain constant over time.HashMap
is non synchronized whereasHashtable
is synchronized.- Iterator in the
HashMap
is fail-safe while the enumerator for theHashtable
is not and throwConcurrentModificationException
if any other Thread modifies the map structurally by adding or removing any element exceptIterator
's ownremove()
method. But this is not a guaranteed behavior and will be done by JVM on best effort.
Note on Some Important Terms:
- Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a
Hashtable
will have to acquire a lock on the object while others will wait for lock to be released. - Fail-safe is relevant within the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object "structurally", a concurrent modification exception will be thrown. It is possible for other threads though to invoke
set
method since it doesn't modify the collection "structurally". However, if prior to callingset
, the collection has been modified structurally,IllegalArgumentException
will be thrown. - Structurally modification means deleting or inserting element which could effectively change the structure of map.
HashMap
can be synchronized by
Map m = Collections.synchronizeMap(hashMap);
Map provides Collection views instead of direct support for iteration
via Enumeration objects. Collection views greatly enhance the
expressiveness of the interface, as discussed later in this section.
Map allows you to iterate over keys, values, or key-value pairs;
Hashtable
does not provide the third option. Map provides a safe way
to remove entries in the midst of iteration; Hashtable
did not.
Finally, Map fixes a minor deficiency in the Hashtable
interface.
Hashtable
has a method called contains, which returns true if the
Hashtable
contains a given value. Given its name, you'd expect this
method to return true if the Hashtable
contained a given key, because
the key is the primary access mechanism for a Hashtable
. The Map
interface eliminates this source of confusion by renaming the method
containsValue
. Also, this improves the interface's consistency —
containsValue
parallels containsKey
.
HashMap
: An implementation of the Map
interface that uses hash codes to index an array.
Hashtable
: Hi, 1998 called. They want their collections API back.
Seriously though, you're better off staying away from Hashtable
altogether. For single-threaded apps, you don't need the extra overhead of synchronisation. For highly concurrent apps, the paranoid synchronisation might lead to starvation, deadlocks, or unnecessary garbage collection pauses. Like Tim Howland pointed out, you might use ConcurrentHashMap
instead.
Keep in mind that HashTable
was legacy class before Java Collections Framework (JCF) was introduced and was later retrofitted to implement the Map
interface. So was Vector
and Stack
.
Therefore, always stay away from them in new code since there always better alternative in the JCF as others had pointed out.
Here is the Java collection cheat sheet that you will find useful. Notice the gray block contains the legacy class HashTable,Vector and Stack.