Map is one of the most important data structures in Java. In this post, I will illustrate how to use different types of maps, such as HashMap, TreeMap, HashTable and LinkedHashMap.
1. Map Overview
There are 4 commonly used implementations of Map in Java SE - HashMap, TreeMap, Hashtable and LinkedHashMap. If we use only one sentence to describe each implementation, it would be the following:
HashMap is implemented as a hash table, and there is no ordering on keys or values.
TreeMap is implemented based on red-black tree structure, and it is ordered by the key.
LinkedHashMap preserves the insertion order
Hashtable is synchronized, in contrast to HashMap. It has an overhead for synchronization.
This is the reason that HashMap should be used if the program is thread-safe.
2. HashMap
If the key of a HashMap is a self-defined object, then the equals() and hashCode() contract need to be followed.
Dog(String c) { color = c; } public String toString(){ return color + " dog"; } }
publicclassTestHashMap{ publicstaticvoidmain(String[] args){ HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>(); Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("white"); Dog d4 = new Dog("white");
4 white dog - 5 black dog - 15 red dog - 10 white dog - 20
Note here, we add “white dogs” twice by mistake, but the HashMap accepts it. This does not make sense, because now we are confused with how many white dogs are really there.
public String toString(){ return color + " dog"; } }
Now the output is:
1 2 3 4
3 red dog - 10 white dog - 20 black dog - 15
The reason is that HashMap doesn’t allow two identical elements. By default, the hashCode() and equals() methods implemented in the Object class are used. The default hashCode() method gives distinct integers for distinct objects, and the equals() method only returns true when two references refer to the same object. Check out the hashCode() and equals() contract if this is not obvious to you.
Check out the most frequently used methods for HashMap, such as iteration, print, etc.
3. TreeMap
A TreeMap is sorted by keys. Let’s first take a look at the following example to understand the “sorted by keys” idea.
Dog(String c) { color = c; } publicbooleanequals(Object o){ return ((Dog) o).color.equals(this.color); }
publicinthashCode(){ return color.length(); } public String toString(){ return color + " dog"; } }
publicclassTestTreeMap{ publicstaticvoidmain(String[] args){ Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("white"); Dog d4 = new Dog("white");
Exception in thread "main" java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable at java.util.TreeMap.put(Unknown Source) at collection.TestHashMap.main(TestHashMap.java:35)
Since TreeMaps are sorted by keys, the object for key has to be able to compare with each other, that’s why it has to implement Comparable interface. For example, you use String as key, because String implements Comparable interface.
publicclassTestTreeMap{ publicstaticvoidmain(String[] args){ Dog d1 = new Dog("red", 30); Dog d2 = new Dog("black", 20); Dog d3 = new Dog("white", 10); Dog d4 = new Dog("white", 10);