Differences between Map implementations - HashMap, TreeMap, LinkedHashMap, WeakHashMap, IdentityHashMap, EnumMap


Hi, I am Malathi Boggavarapu working at Volvo Group and i live in Gothenburg, Sweden. I have been working on Java since several years and had vast experience and knowledge across various technologies.


HashMap, TreeMap, LinkedHashMap, WeakHAshMap, IdentityHashMap, EnumMap

   
  • 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. Key object should implement Comparable interface inorder to compare with other keys and maintain sorted order. 
TreeMap is not synchronized. We can make it synchronized by using Collections.synchronizedMap method.

Ex: Simple example which outputs the natural ordering of key elements. 

Map treeMap = new TreeMap();
treeMap.put("f",10);
treeMap.put("d", 4);
treeMap.put("a", 1);
treeMap.put("b", 2);

output : a=1,
b=2,
d=4,
f=10,

If objects are used as keys, own comparator should be used by implementing Comparable interface


Key k1 = new Key(1, "Malathi");

Key k2 = new Key(2, "Neelima");

treeMap.put(k1, "val1");

treeMap.put(k2, "val2");
Set entries = treeMap.entrySet();
Iterator it = entries.iterator();
while(it.hasNext()) {
System.out.println(it.next() + ",");
}

If object Key does not implement Comparator interface, it throws following exception.

Exception in thread "main" java.lang.ClassCastException: mapEx.Key cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(Unknown Source) at java.util.TreeMap.put(Unknown Source) at mapEx.MapImplEx.main(MapImplEx.java:18)

Otherwise, output shows depending on the implementation of compare method.

  • LinkedHashMap preserves the insertion order. whatever order the elements are inserted, the order is preserved. HashMap does not preserve the order of elements.
Ex: 


Map map = new LinkedHashMap<>();

map.put("A", 1);

map.put("M", 7);

map.put("N", 10);

output: It jsut output the insertion order of the elements whereas HashMap does not preserve the order.

A=1,
M=7,
N=10,

  • WeakHashMap: Hash table based implementation of the Map interface, with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. This class is not synchronized and can make it by using Collections.synchronized method.
Example:


Map map = new WeakHashMap();

      map.put(new String("Malathi", "Boggavarapu");

      

      Runnable runner = new Runnable() {
         public void run() {
            while (map.containsKey("Maine")) {
               try {
                  Thread.sleep(500);
               } catch (InterruptedException ignored) {
               }
               System.out.println("Thread waiting");
               System.gc();
            }
         }
      };
      Thread t = new Thread(runner);
      t.start();
      System.out.println("Main waiting");
      try {
         t.join();
      } catch (InterruptedException ignored) {
      }

output :Main waiting
Thread waiting

  • IdentityHashMap:  IdentityHashMap as name suggests uses the equality operator(==) for comparing the keys. So when you put any Key Value pair in it the Key Object is compared using == operator.
Example:


  ihm.put("Malathi", new Double(3434.34));

      ihm.put("Neelima", new Double(123.22));

      ihm.put("Anvi", new Double(1378.00));

      ihm.put("Naresh", new Double(99.22));
      ihm.put("Chaitu", new Double(-19.08));
      
      // Get a set of the entries
      Set set = ihm.entrySet();
      
      // Get an iterator
      Iterator i = set.iterator();
      
      // Display elements
      while(i.hasNext()) {
         Map.Entry me = (Map.Entry)i.next();
         System.out.print(me.getKey() + ": ");
         System.out.println(me.getValue());
      }
      System.out.println();
      
      // Deposit 1000 into Zara's account
      double balance = ((Double)ihm.get("Malathi")).doubleValue();
      ihm.put("Malathi", new Double(balance + 1000));
      System.out.println("Malathi's new balance: " + ihm.get("Malathi"));


output:

Malathi: 3434.34
Neelima: 123.22
Anvi: 1378.00
Naresh:99.22
Chaitu: -19.08
Malathi's new balance: 4434.34

EnumMap

A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.

Enum maps are maintained in the natural order of their keys (the order in which the enum constants are declared). This is reflected in the iterators returned by the collections views (keySet()entrySet(), and values()).

Iterators returned by the collection views are weakly consistent: they will never throw ConcurrentModificationException and they may or may not show the effects of any modifications to the map that occur while the iteration is in progress.

Null keys are not permitted. Attempts to insert a null key will throw NullPointerException. Attempts to test for the presence of a null key or to remove one will, however, function properly. Null values are permitted.

Like most collection implementations EnumMap is not synchronized but can be made synchronized using Collections.synchronizedMap()

The main difference between HashMap and EnumMap is the probability of Collision. Since Enum is internally maintained as array and they are stored in their natural order using ordinal(), as shown in following code which is taken from put() method of EnumMap

    int index = ((Enum)key).ordinal();
    Object oldValue = vals[index];
    vals[index] = maskNull(value);

Since EnumMap doesn't call hashCode method on keys, there is no chance of collision.



Comments

Popular posts from this blog

Bash - Execute Pl/Sql script from Shell script

Gradle Fundamentals

Load Balancing using Spring Cloud Netflix Ribbon