Java's hashmap: Is keys() indeed missing? - java

Java's HashTable is a synchronized hashtable (and exists for quite a while) while HashMap is an unsynchronized.
In HashTable there are 2 ways to get the keys of the hashtable:
Keys which:
key
public Enumeration keys()Returns an enumeration of the keys in
this hashtable.
and
public Set keySet()
Returns a Set view of the keys contained in this
Hashtable. The Set is backed by the Hashtable, so changes to the
Hashtable are reflected in the Set, and vice-versa. The Set supports
element removal (which removes the corresponding entry from the
Hashtable), but not element addition.
In the latter it is explicitely stated that the keys are direct references to the hashtable (so beware of modifications etc).
But there is no such mention for the keys().
So my question is:
Does the keys() using an enumerator return a copy of the keys (unlike keyset() which return the actual keys)?
And if yes why there is no such method in HashMap and only keyset() is provided?

Hashtable.keys returns references to the real keys. It does not copy them.
The method does not exist in HashMap because keySet already does the job. It exists in hashtable because this class has been around since java 1.0. The collections framework that defines the keySet method wasn't added until 1.2.

In general Iterators on unsynchronized collections don't behave particularly well (they tend to throw ConcurrentModificationException or behave in an unspecified manner)
By looking at the source code for Hashtable, you can see that the key set's iterator and keys() enumeration are in fact implemented by the same inner class, which will attempt to throw a ConcurrentModificationException if the Hashtable changes. So, no, it is not going to make a copy of the keys.

Related

Why do we need hashcode and bucket in LinkedHashMap

Lately,I've been going through implementations of Map interface in java. I understood HashMap and everything made sense.
But when it comes to LinkedHashMap, as per my knowledge so far, the Entry has key, value, before and after. where before and after keeps track of order of insertion.
However, using hashcode and bucket concept doesn't make sense to me in LinkedHashMaps.
I went through this article for understanding implementation of linkedHashMaps
Could someone please explain it? I mean why does it matter in which bucket we put the entry node. In fact why bucket concept in the first place.? why not plain doubly llinked lists?
LinkedHashMap is still a type of a HashMap. It uses the same logic as HashMap in order to find the bucket where a key belongs (used in methods such as get(),put(),containsKey(),etc...). The hashCode() is used to locate that bucket. This logic is essential for the expected O(1) performance of these operations.
The added functionality of LinkedHashMap (which uses the before and after references) is only used to iterate the entries according to insertion order, so it affects the iterators of the Collections returned by the keySet(),entrySet() & values() methods. It doesn't affect where the entries are stored.
Without hashcodes and buckets, LinkedHashMap won't be able to lookup keys in the Map in O(1) expected time.

Is looping through keySet() in LinkedHashMap exactly the same as using an iterator [duplicate]

I know LinkedHashMap has a predictable iteration order (insertion order). Does the Set returned by LinkedHashMap.keySet() and the Collection returned by LinkedHashMap.values() also maintain this order?
The Map interface provides three
collection views, which allow a map's contents to be viewed as a set
of keys, collection of values, or set
of key-value mappings. The order of
a map is defined as the order in which
the iterators on the map's collection
views return their elements. Some map
implementations, like the TreeMap
class, make specific guarantees as to
their order; others, like the
HashMap class, do not.
-- Map
This linked list defines the iteration
ordering, which is normally the order
in which keys were inserted into the
map (insertion-order).
-- LinkedHashMap
So, yes, keySet(), values(), and entrySet() (the three collection views mentioned) return values in the order the internal linked list uses. And yes, the JavaDoc for Map and LinkedHashMap guarantee it.
That is the point of this class, after all.
Looking at the source, it looks like it does. keySet(), values(), and entrySet() all use the same entry iterator internally.
Don't get confused with LinkedHashMap.keySet() and LinkedHashMap.entrySet() returning Set and hence it should not guarantee ordering !
Set is an interface with HashSet,TreeSet etc beings its implementations. The HashSet implementation of Set interface does not guarantees ordering. But TreeSet does. Also LinkedHashSet does.
Therefore it depends on how Set has been implemented in LinkedHashMap to know whether the returning Set reference will guarantee ordering or not.
I went through the source code of LinkedHashMap, it looks like this:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Thus LinkedHashMap/HashMap has its own implementation of Set i.e. KeySet. Thus don't confuse this with HashSet.
Also, the order is maintained by how the elements are inserted into the bucket. Look at the addEntry(..) method of LinkedHashMap and compare it with that of HashMap which highlights the main difference between HashMap and LinkedHashMap.
You can assume so. The Javadoc says 'predictable iteration order', and the only iterators available in a Map are those for the keySet(), entrySet(), and values().
So in the absence of any further qualification it is clearly intended to apply to all of those iterators.
AFAIK it is not documented so you cannot "formally" assume so. It is unlikely, however, that the current implementation would change.
If you want to ensure order, you may want to iterate over the map entires and insert them into a sorted set with an order function of your choice, though you will be paying a performance cost, naturally.

Why HashSet internally implemented as HashMap [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why does HashSet implementation in Sun Java use HashMap as its backing?
I know what a hashset and hashmap is - pretty well versed with them.
There is 1 thing which really puzzled me.
Example:
Set <String> testing= new HashSet <String>();
Now if you debug it using eclipse right after the above statements, under debugger variables tab, you will noticed that the set 'testing' internally is implemented as a hashmap.
Why does it need a hashmap since there is no key,value pair involved in sets collection
It's an implementation detail. The HashMap is actually used as the backing store for the HashSet. From the docs:
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
(emphasis mine)
The answer is right in the API docs
"This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
This class offers constant time performance for the basic operations (add, remove, contains and size), assuming the hash function disperses the elements properly among the buckets. Iterating over this set requires time proportional to the sum of the HashSet instance's size (the number of elements) plus the "capacity" of the backing HashMap instance (the number of buckets). Thus, it's very important not to set the initial capacity too high (or the load factor too low) if iteration performance is important."
So you don't even need the debugger to know this.
In answer to your question: it is an implementation detail. It doesn't need to use a HashMap, but it is probably just good code re-use. If you think about it, in this case the only difference is that a Set has different semantics from a Map. Namely, maps have a get(key) method, and Sets do not. Sets do not allow duplicates, Maps allow duplicate values, but they must be under different keys.
It is probably really easy to use a HashMap as the backing of a HashSet, because all you would have to do would be to use hashCode (defined on all objects) on the value you are putting in the Set to determine if a dupe, i.e., it is probably just doing something like
backingHashMap.put(toInsert.hashCode(), toInsert);
to insert items into the Set.
In most cases the Set is implemented as wrapper for the keySet() of a Map. This avoids duplicate implementations. If you look at the source you will see how it does this.
You might find the method Collections.newSetFromMap() which can be used to wrap ConcurrentHashMap for example.
The very first sentence of the class's Javadoc states that it is backed by a HashMap:
This class implements the Set interface, backed by a hash table (actually a HashMap instance).
If you'll look at the source code of HashSet you'll see that what it stores in the map is as the key is the entry you are using, and the value is a mere marker Object (named PRESENT).
Why is it backed by a HashMap? Because this is the simplest way to store a set of items in a (conceptual) hashtable and there is no need for HashSet to re-invent an implementation of a hashtable data structure.
It's just a matter of convenience that the standard Java class library implements HashSet using a HashMap -- they only need to implement one data structure and then HashSet stores its data in a HashMap with the actual set objects as the key and a dummy value (typically Boolean.TRUE) as the value.
HashMap has already all the functionality that HashSet requires. There would be no sense to duplicate the same algorithms.
it allows you to easily and quickly determine whether an object is already in the set or not.

Difference between HashSet and HashMap?

Apart from the fact that HashSet does not allow duplicate values, what is the difference between HashMap and HashSet?
I mean implementation wise? It's a little bit vague because both use hash tables to store values.
HashSet is a set, e.g. {1,2,3,4,5}
HashMap is a key -> value (key to value) map, e.g. {a -> 1, b -> 2, c -> 2, d -> 1}
Notice in my example above that in the HashMap there must not be duplicate keys, but it may have duplicate values.
In the HashSet, there must be no duplicate elements.
They are entirely different constructs. A HashMap is an implementation of Map. A Map maps keys to values. The key look up occurs using the hash.
On the other hand, a HashSet is an implementation of Set. A Set is designed to match the mathematical model of a set. A HashSet does use a HashMap to back its implementation, as you noted. However, it implements an entirely different interface.
When you are looking for what will be the best Collection for your purposes, this Tutorial is a good starting place. If you truly want to know what's going on, there's a book for that, too.
HashSet
HashSet class implements the Set interface
In HashSet, we store objects(elements or values)
e.g. If we have a HashSet of string elements then it could depict a
set of HashSet elements: {“Hello”, “Hi”, “Bye”, “Run”}
HashSet does not allow duplicate elements that mean you
can not store duplicate values in HashSet.
HashSet permits to have a single null value.
HashSet is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]
add contains next notes
HashSet O(1) O(1) O(h/n) h is the table
HashMap
HashMap class implements the Map interface
HashMap is
used for storing key & value pairs. In short, it maintains the
mapping of key & value (The HashMap class is roughly equivalent to
Hashtable, except that it is unsynchronized and permits nulls.) This
is how you could represent HashMap elements if it has integer key
and value of String type: e.g. {1->”Hello”, 2->”Hi”, 3->”Bye”,
4->”Run”}
HashMap does not allow duplicate keys however it allows having duplicate values.
HashMap permits single null key and any number of null values.
HashMap is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]
get containsKey next Notes
HashMap O(1) O(1) O(h/n) h is the table
Please refer this article to find more information.
It's really a shame that both their names start with Hash. That's the least important part of them. The important parts come after the Hash - the Set and Map, as others have pointed out. What they are, respectively, are a Set - an unordered collection - and a Map - a collection with keyed access. They happen to be implemented with hashes - that's where the names come from - but their essence is hidden behind that part of their names.
Don't be confused by their names; they are deeply different things.
The Hashset Internally implements HashMap. If you see the internal implementation the values inserted in HashSet are stored as keys in the HashMap and the value is a Dummy object of Object class.
Difference between HashMap vs HashSet is:-
HashMap contains key value pairs and each value can be accessed by key where as HashSet needs to be iterated everytime as there is no get method.
HashMap implements Map interface and allows one null value as a key and multiple null values as values, whereas HashSet implements Set interface, allows only one null value and no duplicated values.(Remeber one null key is allowed in HashMap key hence one null value in HashSet as HashSet implemements HashMap internally).
HashSet and HashMap do not maintain the order of insertion while iterating.
HashSet allows us to store objects in the set where as HashMap allows us to store objects on the basis of key and value. Every object or stored object will be having key.
As the names imply, a HashMap is an associative Map (mapping from a key to a value), a HashSet is just a Set.
Differences between HashSet and HashMap in Java
1) First and most significant difference between HashMap and HashSet is that HashMap is an implementation of Map interface while HashSet is an implementation of Set interface, which means HashMap is a key value based data-structure and HashSet guarantees uniqueness by not allowing duplicates.In reality HashSet is a wrapper around HashMap in Java, if you look at the code of add(E e) method of HashSet.java you will see following code :
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
where its putting Object into map as key and value is an final object PRESENT which is dummy.
2) Second difference between HashMap and HashSet is that , we use add() method to put elements into Set but we use put() method to insert key and value into HashMap in Java.
3) HashSet allows only one null key, but HashMap can allow one null key + multiple null values.
That's all on difference between HashSet and HashMap in Java. In summary HashSet and HashMap are two different type of Collection one being Set and other being Map.
Differences between HashSet and HashMap in Java
HashSet internally uses HashMap to store objects.when add(String) method called it calls HahsMap put(key,value) method where key=String object & value=new Object(Dummy).so it maintain no duplicates because keys are nothing but Value Object.
the Objects which are stored as key in Hashset/HashMap should override hashcode & equals contract.
Keys which are used to access/store value objects in HashMap should declared as Final because when it is modified Value object can't be located & returns null.
A HashMap is to add, get, remove, ... objects indexed by a custom key of any type.
A HashSet is to add elements, remove elements and check if elements are present by comparing their hashes.
So a HashMap contains the elements and a HashSet remembers their hashes.
A HashSet uses a HashMap internally to store its entries. Each entry in the internal HashMap is keyed by a single Object, so all entries hash into the same bucket. I don't recall what the internal HashMap uses to store its values, but it doesn't really matter since that internal container will never contain duplicate values.
EDIT: To address Matthew's comment, he's right; I had it backwards. The internal HashMap is keyed with the Objects that make up the Set elements. The values of the HashMap are an Object that's just simply stored in the HashMap buckets.
Differences:
with respect to heirarchy:
HashSet implements Set.
HashMap implements Map and stores a mapping of keys and values.
A use of HashSet and HashMap with respect to database would help you understand the significance of each.
HashSet: is generally used for storing unique collection objects.
E.g: It might be used as implementation class for storing many-to-one relation ship between
class Item and Class Bid where (Item has many Bids)
HashMap: is used to map a key to value.the value may be null or any Object /list of Object (which is object in itself).
A HashSet is implemented in terms of a HashMap. It's a mapping between the key and a PRESENT object.
HashMap is a Map implementation, allowing duplicate values but not duplicate keys.. For adding an object a Key/Value pair is required. Null Keys and Null values are allowed. eg:
{The->3,world->5,is->2,nice->4}
HashSet is a Set implementation,which does not allow duplicates.If you tried to add a duplicate object, a call to public boolean add(Object o) method, then the set remains unchanged and returns false. eg:
[The,world,is,nice]
Basically in HashMap, user has to provide both Key and Value, whereas in HashSet you provide only Value, the Key is derived automatically from Value by using hash function. So after having both Key and Value, HashSet can be stored as HashMap internally.
HashSet and HashMap both store pairs , the difference lies that in HashMap you can specify a key while in HashSet the key comes from object's hash code
HashMaps allow one null key and null values. They are not synchronized, which increases efficiency. If it is required, you can make them synchronized using Collections.SynchronizedMap()
Hashtables don't allow null keys and are synchronized.
The main difference between them you can find as follows:
HashSet
It does not allow duplicate keys.
Even it is not synchronized, so this will have better performance.
It allows a null key.
HashSet can be used when you want to maintain a unique list.
HashSet implements Set interface and it is backed by the hash table(actually HashMap instance).
HashSet stores objects.
HashSet doesn’t allow duplicate elements but null values are allowed.
This interface doesn’t guarantee that order will remain constant over time.
HashMap
It allows duplicate keys.
It is not synchronized, so this will have better performance.
HashMap does not maintain insertion order.
The order is defined by the Hash function.
It is not Thread Safe
It allows null for both key and value.
It allows one null key and as many null values as you like.
HashMap is a Hash table-based implementation of the Map interface.
HashMap store object as key and value pair.
HashMap does not allow duplicate keys but null keys and values are allowed.
Ordering of the element is not guaranteed overtime.
EDIT - this answer isn't correct. I'm leaving it here in case other people have a similar idea. b.roth and justkt have the correct answers above.
--- original ---
you pretty much answered your own question - hashset doesn't allow duplicate values. it would be trivial to build a hashset using a backing hashmap (and just a check to see if the value already exists). i guess the various java implementations either do that, or implement some custom code to do it more efficiently.
HashMap is a implementation of Map interface
HashSet is an implementation of Set Interface
HashMap Stores data in form of key value pair
HashSet Store only objects
Put method is used to add element in map
Add method is used to add element is Set
In hash map hashcode value is calculated using key object
Here member object is used for calculating hashcode value which can be same for two objects so equal () method is used to check for equality if it returns false that means two objects are different.
HashMap is faster than hashset because unique key is used to access object
HashSet is slower than Hashmap

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:
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. 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);
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 interviews to check whether the candidate understands the correct usage of collection classes and is 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 in 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 the 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 the 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 the 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.
The Map Interface
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.
There are many good answers already posted. I'm adding few new points and summarizing it.
HashMap and Hashtable both are used to store data in key and value form. Both are using hashing technique to store unique keys.
But there are many differences between HashMap and Hashtable classes that are given below.
HashMap
HashMap is non synchronized. It is not-thread safe and can't be shared between many threads without proper synchronization code.
HashMap allows one null key and multiple null values.
HashMap is a new class introduced in JDK 1.2.
HashMap is fast.
We can make the HashMap as synchronized by calling this code
Map m = Collections.synchronizedMap(HashMap);
HashMap is traversed by Iterator.
Iterator in HashMap is fail-fast.
HashMap inherits AbstractMap class.
Hashtable
Hashtable is synchronized. It is thread-safe and can be shared with many threads.
Hashtable doesn't allow null key or value.
Hashtable is a legacy class.
Hashtable is slow.
Hashtable is internally synchronized and can't be unsynchronized.
Hashtable is traversed by Enumerator and Iterator.
Enumerator in Hashtable is not fail-fast.
Hashtable inherits Dictionary class.
Further reading What is difference between HashMap and Hashtable in Java?
Take a look at this chart. It provides comparisons between different data structures along with HashMap and Hashtable. The comparison is precise, clear and easy to understand.
Java Collection Matrix
In addition to what izb said, HashMap allows null values, whereas the Hashtable does not.
Also note that Hashtable extends the Dictionary class, which as the Javadocs state, is obsolete and has been replaced by the Map interface.
Hashtable is similar to the HashMap and has a similar interface. It is recommended that you use HashMap, unless you 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.
Hashtable is synchronized, whereas HashMap isn't. That makes Hashtable slower than Hashmap.
For single thread applications, use HashMap since they are otherwise the same in terms of functionality.
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
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:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
Update: No, they won't land in 1.8... :(
Are Project Coin's collection enhancements going to be in JDK8?
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.
HashMap and Hashtable have significant algorithmic differences as well. No one has mentioned this before so that's why I am bringing it up. HashMap will construct a hash table with power of two size, increase it dynamically such that you have at most about eight elements (collisions) in any bucket and will stir the elements very well for general element types. However, the Hashtable implementation provides better and finer control over the hashing if you know what you are doing, namely you can fix the table size using e.g. the closest prime number to your values domain size and this will result in better performance than HashMap i.e. less collisions for some cases.
Separate from the obvious differences discussed extensively in this question, I see the Hashtable as a "manual drive" car where you have better control over the hashing and the HashMap as the "automatic drive" counterpart that will generally perform well.
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.
A Collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data. A collections framework W is a unified architecture for representing and manipulating collections.
The HashMap JDK1.2 and Hashtable JDK1.0, both are used to represent a group of objects that are represented in <Key, Value> pair. Each <Key, Value> pair is called Entry object. The collection of Entries is referred by the object of HashMap and Hashtable. Keys in a collection must be unique or distinctive. [as they are used to retrieve a mapped value a particular key. values in a collection can be duplicated.]
« Superclass, Legacy and Collection Framework member
Hashtable is a legacy class introduced in JDK1.0, which is a subclass of Dictionary class. From JDK1.2 Hashtable is re-engineered to implement the Map interface to make a member of collection framework. HashMap is a member of Java Collection Framework right from the beginning of its introduction in JDK1.2. HashMap is the subclass of the AbstractMap class.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« Initial capacity and Load factor
The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. Note that the hash table is open: in the case of a "hash collision", a single bucket stores multiple entries, which must be searched sequentially. The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased.
HashMap constructs an empty hash table with the default initial capacity (16) and the default load factor (0.75). Where as Hashtable constructs empty hashtable with a default initial capacity (11) and load factor/fill ratio (0.75).
« Structural modification in case of hash collision
HashMap, Hashtable in case of hash collisions they store the map entries in linked lists. From Java8 for HashMap if hash bucket grows beyond a certain threshold, that bucket will switch from linked list of entries to a balanced tree. which improve worst-case performance from O(n) to O(log n). While converting the list to binary tree, hashcode is used as a branching variable. If there are two different hashcodes in the same bucket, one is considered bigger and goes to the right of the tree and other one to the left. But when both the hashcodes are equal, HashMap assumes that the keys are comparable, and compares the key to determine the direction so that some order can be maintained. It is a good practice to make the keys of HashMap comparable. On adding entries if bucket size reaches TREEIFY_THRESHOLD = 8 convert linked list of entries to a balanced tree, on removing entries less than TREEIFY_THRESHOLD and at most UNTREEIFY_THRESHOLD = 6 will reconvert balanced tree to linked list of entries. Java 8 SRC, stackpost
« Collection-view iteration, Fail-Fast and Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator is a fail-fast in nature. i.e it throws ConcurrentModificationException if a collection is modified while iterating other than it’s own remove() method. Where as Enumeration is fail-safe in nature. It doesn’t throw any exceptions if a collection is modified while iterating.
According to Java API Docs, Iterator is always preferred over the Enumeration.
NOTE: The functionality of Enumeration interface is duplicated by the Iterator interface. In addition, Iterator adds an optional remove operation, and has shorter method names. New implementations should consider using Iterator in preference to Enumeration.
In Java 5 introduced ConcurrentMap Interface: ConcurrentHashMap - a highly concurrent, high-performance ConcurrentMap implementation backed by a hash table. This implementation never blocks when performing retrievals and allows the client to select the concurrency level for updates. It is intended as a drop-in replacement for Hashtable: in addition to implementing ConcurrentMap, it supports all of the "legacy" methods peculiar to Hashtable.
Each HashMapEntrys value is volatile thereby ensuring fine grain consistency for contended modifications and subsequent reads; each read reflects the most recently completed update
Iterators and Enumerations are Fail Safe - reflecting the state at some point since the creation of iterator/enumeration; this allows for simultaneous reads and modifications at the cost of reduced consistency. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.
Like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value.
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
#Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
#Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« Null Keys And Null Values
HashMap allows maximum one null key and any number of null values. Where as Hashtable doesn’t allow even a single null key and null value, if the key or value null is then it throws NullPointerException. Example
« Synchronized, Thread Safe
Hashtable is internally synchronized. Therefore, it is very much safe to use Hashtable in multi threaded applications. Where as HashMap is not internally synchronized. Therefore, it is not safe to use HashMap in multi threaded applications without external synchronization. You can externally synchronize HashMap using Collections.synchronizedMap() method.
« Performance
As Hashtable is internally synchronized, this makes Hashtable slightly slower than the HashMap.
#See
A red–black tree is a kind of self-balancing binary search tree
Performance Improvement for HashMap in Java 8
For threaded apps, you can often get away with ConcurrentHashMap- depends on your performance requirements.
1.Hashmap and HashTable both store key and value.
2.Hashmap can store one key as null. Hashtable can't store null.
3.HashMap is not synchronized but Hashtable is synchronized.
4.HashMap can be synchronized with Collection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
Apart from the differences already mentioned, it should be noted that since Java 8, HashMap dynamically replaces the Nodes (linked list) used in each bucket with TreeNodes (red-black tree), so that even if high hash collisions exist, the worst case when searching is
O(log(n)) for HashMap Vs O(n) in Hashtable.
*The aforementioned improvement has not been applied to Hashtable yet, but only to HashMap, LinkedHashMap, and ConcurrentHashMap.
FYI, currently,
TREEIFY_THRESHOLD = 8 : if a bucket contains more than 8 nodes, the linked list is transformed into a balanced tree.
UNTREEIFY_THRESHOLD = 6 : when a bucket becomes too small (due to removal or resizing) the tree is converted back to linked list.
There are 5 basic differentiations with HashTable and HashMaps.
Maps allows you to iterate and retrieve keys, values, and both key-value pairs as well, Where HashTable don't have all this capability.
In Hashtable there is a function contains(), which is very confusing to use. Because the meaning of contains is slightly deviating. Whether it means contains key or contains value? tough to understand. Same thing in Maps we have ContainsKey() and ContainsValue() functions, which are very easy to understand.
In hashmap you can remove element while iterating, safely. where as it is not possible in hashtables.
HashTables are by default synchronized, so it can be used with multiple threads easily. Where as HashMaps are not synchronized by default, so can be used with only single thread. But you can still convert HashMap to synchronized by using Collections util class's synchronizedMap(Map m) function.
HashTable won't allow null keys or null values. Where as HashMap allows one null key, and multiple null values.
My small contribution :
First and most significant different between Hashtable and HashMap is that, HashMap is not thread-safe while Hashtable is a thread-safe collection.
Second important difference between Hashtable and HashMap is performance, since HashMap is not synchronized it perform better than Hashtable.
Third difference on Hashtable vs HashMap is that Hashtable is obsolete class and you should be using ConcurrentHashMap in place of Hashtable in Java.
HashMap: It is a class available inside java.util package and it is used to store the element in key and value format.
Hashtable: It is a legacy class which is being recognized inside collection framework.
Hashtable is synchronized whereas HashMap is not.
Another difference is that iterator in the HashMap is fail-safe
while the enumerator for the Hashtable isn't. If you change the map
while iterating, you'll know.
HashMap permits null values in it, while Hashtable doesn't.
HashTable is a legacy class in the jdk that shouldn't be used anymore. Replace usages of it with ConcurrentHashMap. If you don't require thread safety, use HashMap which isn't threadsafe but faster and uses less memory.
HashMap and HashTable
Some important points about HashMap and HashTable.
please read below details.
1) Hashtable and Hashmap implement the java.util.Map interface
2) Both Hashmap and Hashtable is the hash based collection. and working on hashing.
so these are similarity of HashMap and HashTable.
What is the difference between HashMap and HashTable?
1) First difference is HashMap is not thread safe While HashTable is ThreadSafe
2) HashMap is performance wise better because it is not thread safe. while Hashtable performance wise is not better because it is thread safe. so multiple thread can not access Hashtable at the same time.
HashMap and Hashtable both are used to store data in key and value form. Both are using hashing technique to store unique keys.
ut there are many differences between HashMap and Hashtable classes that are given below.
Hashtable:
Hashtable is a data structure that retains values of key-value pair. It doesn’t allow null for both the keys and the values. You will get a NullPointerException if you add null value. It is synchronized. So it comes with its cost. Only one thread can access HashTable at a particular time.
Example :
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
HashMap:
HashMap is like Hashtable but it also accepts key value pair. It allows null for both the keys and the values. Its performance better is better than HashTable, because it is unsynchronized.
Example:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
Since Hashtable in Java is a subclass of Dictionary class which is now obsolete due to the existence of Map Interface, it is not used anymore. Moreover, there isn't anything you can't do with a class that implements the Map Interface that you can do with a Hashtable.
Old and classic topic, just want to add this helpful blog that explains this:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
Blog by Manish Chhabra
The 5 main differences betwen HashMap and Hashtable
HashMap and Hashtable both implement java.util.Map interface but there
are some differences that Java developers must understand to write
more efficient code. As of the Java 2 platform v1.2, Hashtable class
was retrofitted to implement the Map interface, making it a member of
the Java Collections Framework.
One of the major differences between HashMap and Hashtable is that HashMap is non-synchronized whereas Hashtable is synchronized, which
means Hashtable is thread-safe and can be shared between multiple
threads but HashMap cannot be shared between multiple threads without
proper synchronization. Java 5 introduced ConcurrentHashMap which is
an alternative of Hashtable and provides better scalability than
Hashtable in Java.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.
The HashMap class is roughly equivalent to Hashtable, except that it permits nulls. (HashMap allows null values as key and value whereas
Hashtable doesn’t allow nulls).
The third significant difference between HashMap vs Hashtable is that Iterator in the HashMap is a fail-fast iterator 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. This is also an important difference
between Enumeration and Iterator in Java.
One more notable difference between Hashtable and HashMap is that because of thread-safety and synchronization Hashtable is much slower
than HashMap if used in Single threaded environment. So if you don’t
need synchronization and HashMap is only used by one thread, it out
perform Hashtable in Java.
HashMap does not guarantee that the order of the map will remain constant over time.
Note that HashMap can be synchronized by
Map m = Collections.synchronizedMap(hashMap);
In Summary there are significant differences between Hashtable and
HashMap in Java e.g. thread-safety and speed and based upon that only
use Hashtable if you absolutely need thread-safety, if you are running
Java 5 consider using ConcurrentHashMap in Java.

Categories

Resources