Ccna final exam - java, php, javascript, ios, cshap all in one. This is a collaboratively edited question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.
Friday, May 25, 2012
Differences between HashMap and Hashtable?
What is the difference 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:
Hashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones. Hashtable does not allow null keys or values. HashMap allows one null key and any number of null 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 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.
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:
No one's mentioned the fact that Hashtable is not part of the Java Collections Framework - it just provides a similar API. Also, 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 oftenly asked in interview to check whether candidate understand correct usage of collection classes and aware of alternative solutions available.
The HashMap class is roughly equivalent to Hashtable, except that it is non synchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn't allow nulls). HashMap does not guarantee that the order of the map will remain constant over time. HashMap is non synchronized whereas Hashtable is synchronized. Iterator in the HashMap is fail-safe while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally by adding or removing any element except Iterator's own remove() 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 from 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 wjavascript:void(0)ill 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 calling "set", 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: An implementation of the Map interface that uses a lookup table of hashcodes to locate keys. 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 syncrhonisation. 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.
As I understand it, Hashtable is similar to the HashMap and has a similar interface. It is recommended that you use HashMap unless yoou require support for legacy applications or you need synchronisation - as the Hashtables methods are synchronised. So in your case as you are not multi-threading, HashMaps are your best bet.
Another key difference between hashtable and hashmap is that Iterator in the HashMap is fail-fast while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally by adding or removing any element except Iterator's own remove() method. But this is not a guaranteed behavior and will be done by JVM on best effort."
My source: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
Based on the info here, I'd recommend going with HashMap. I think the biggest advantage is that Java will prevent you from modifying it while you are iterating over it, unless you do it through the iterator.
Beside all the other important aspects already mentioned here, Collections API (e.g. Map interface) is being modified all the time to conform to the "latest and greatest" additions to Java spec.
For example, compare Java 5 Map iterating:
for (Elem elem : map.keys()) { elem.doSth(); }
versus the old Hashtable approach:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) { Elem elem = (Elem) en.nextElement(); elem.doSth(); }
In Java 1.8 we are also promised to be able to construct and access HashMaps like in good old scripting languages:
HashTable is synchronized, if you are using it in a single thread you can use HashMap, which is an unsynchronized version. Unsynchronized objects are often a little more performant. By the way if multiple threads access a HashMap concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. Youn can wrap a unsynchronized map in a synchronized one using :
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable can only contain non-null object as a key or as a value. HashMap can contain one null key and null values. The iterators returned by Map are fail-fast, if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. Whereas the Enumerations returned by Hashtable's keys and elements methods are not fail-fast. HashTable and HashMap are member of the Java Collections Framework (since Java 2 platform v1.2, HashTable was retrofitted to implement the Map interface). HashTable is considered legacy code, the documentation advise to use ConcurrentHashMap in place of Hashtable if a thread-safe highly-concurrent implementation is desired. HashMap doesn't guarantee the order in which elements are returned. For HashTable I guess it's the same but I'm not entirely sure, I don't find ressource that clearly state that.
There are several differences between HashMap and Hashtable in Java:
ReplyDeleteHashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.
Hashtable does not allow null keys or values. HashMap allows one null key and any number of null 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 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.
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.
ReplyDeleteA 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)
No one's mentioned the fact that Hashtable is not part of the Java Collections Framework - it just provides a similar API. Also, 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.
ReplyDeleteIn addition to what izb said, HashMap allows null values, whereas the Hashtable does not.
ReplyDeleteAlso note that Hashtable extends the Dictionary class, which as the Javadocs state, is obsolete and has been replaced by the Map interface.
This question oftenly asked in interview to check whether candidate understand correct usage of collection classes and aware of alternative solutions available.
ReplyDeleteThe HashMap class is roughly equivalent to Hashtable, except that it is non synchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn't allow nulls).
HashMap does not guarantee that the order of the map will remain constant over time.
HashMap is non synchronized whereas Hashtable is synchronized.
Iterator in the HashMap is fail-safe while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally by adding or removing any element except Iterator's own remove() 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 from 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 wjavascript:void(0)ill 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 calling "set", 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);
HashMap: An implementation of the Map interface that uses a lookup table of hashcodes to locate keys.
ReplyDeleteHashTable: 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 syncrhonisation. 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.
As I understand it, Hashtable is similar to the HashMap and has a similar interface. It is recommended that you use HashMap unless yoou require support for legacy applications or you need synchronisation - as the Hashtables methods are synchronised. So in your case as you are not multi-threading, HashMaps are your best bet.
ReplyDeleteAnother key difference between hashtable and hashmap is that Iterator in the HashMap is fail-fast while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally by adding or removing any element except Iterator's own remove() method. But this is not a guaranteed behavior and will be done by JVM on best effort."
ReplyDeleteMy source: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
Based on the info here, I'd recommend going with HashMap. I think the biggest advantage is that Java will prevent you from modifying it while you are iterating over it, unless you do it through the iterator.
ReplyDeleteHashtable is synchronized, whereas HashMap isn't. That makes Hashtable slower than Hashmap.
ReplyDeleteFor non-threaded apps, use HashMap since they are otherwise the same in terms of functionality.
For threaded apps, you can often get away with ConcurrentHashMap- depends on your performance requirements.
ReplyDeleteBeside all the other important aspects already mentioned here, Collections API (e.g. Map interface) is being modified all the time to conform to the "latest and greatest" additions to Java spec.
ReplyDeleteFor example, compare Java 5 Map iterating:
for (Elem elem : map.keys()) {
elem.doSth();
}
versus the old Hashtable approach:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
In Java 1.8 we are also promised to be able to construct and access HashMaps like in good old scripting languages:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
HashTable is synchronized, if you are using it in a single thread you can use HashMap, which is an unsynchronized version. Unsynchronized objects are often a little more performant. By the way if multiple threads access a HashMap concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.
ReplyDeleteYoun can wrap a unsynchronized map in a synchronized one using :
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable can only contain non-null object as a key or as a value. HashMap can contain one null key and null values.
The iterators returned by Map are fail-fast, if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. Whereas the Enumerations returned by Hashtable's keys and elements methods are not fail-fast.
HashTable and HashMap are member of the Java Collections Framework (since Java 2 platform v1.2, HashTable was retrofitted to implement the Map interface).
HashTable is considered legacy code, the documentation advise to use ConcurrentHashMap in place of Hashtable if a thread-safe highly-concurrent implementation is desired.
HashMap doesn't guarantee the order in which elements are returned. For HashTable I guess it's the same but I'm not entirely sure, I don't find ressource that clearly state that.