Tags

, , , , ,

After 6 months, I engaged myself to post my next article and I am glad about it :). This article is about Hashmap types and it is for my reference.

Examples are given for few very newer (not used much) types.

HashTable

A very basic implementation of Map interface used to store key – value pairs. The default (key – value ) type is Object, Object. When you create,

new HashTable<Object, Object>(), it creates the hashtable instance to store the default capacity of 11 with load factor as 0.75.

Here, Load factor says in which situation, the hashtable needs to be increased it size. As the default size is 0.75, it increases its size when the elements in hashtable increases its ¾ percent.

As many of know, it is synchronized. Ie, It locks the hashtable whenever the thread is trying to access it and allows only one thread to work on it.

Java 5 introduced ConcurrentHashMap which is an alternative of Hashtable  and provides better scalability than Hashtable in Java.

HashMap

This is other way to store key – value pairs, not synchronized and accepts null (Hashtable won’t accept null as key or value). HashMap cannot be shared between multiple threads  without proper synchronization.

because  of thread-safety and synchronization, Hashtable is much slower than HashMap  if used in Single threaded environment.

It can be synchronized by,

* Map m = Collections.synchronizedMap(hashMap);

You can think of by calling synchronizedMap from collections utility class, you can achieve the behavior of ConcurrentHashMap. But ConcurrentHashMap uses some advanced locking algorithms which makes it more better one than HashMap when working in multi thread environment.

ConcurrentHashMap

It is replacement of hashtable from Java 5 onwards as stated above. It is synchronized whereas HashMap is not. Means only one thread can access concurrentHashMap at one time. It will lock when updating  ConcurrentHashMap so that another thread cannot modify it.

The locking mechanism used by this concurrenthashmap gives better performance as it won’t lock the entire Map which accessing it. ConcurrentHashMap uses several tricks to achieve a high level of concurrency and avoid locking, including using multiple write locks for different hash buckets and exploiting the uncertainties of the JMM to minimize the time that locks are held — or avoid acquiring locks at all. It is optimized for the most common usage, which is retrieving a value likely to already exist in the map. In fact, most successful get() operations will run without any locking at all.

Please refer this site for more details about ConcurrentHashMap: https://www.ibm.com/developerworks/library/j-jtp08223/

TreeMap

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. If you use your own Objects as keys for example, Dog object, then you need to implement Comparable interface and hence have to override compareTo method.

LinkedHashMap

LinkedHashMap is a subclass of HashMap. That means it inherits  the features of HashMap. In addition, the linked list preserves  the insertion-order. ie, Prints in the same order you insert. If you override the value later, the overridden value gets printed for that key.

It accepts null as key or value – remember since it extends HashMap.

WeakHashMap

In WeakHashMap, the keys are not Objects and it is WeakReferences. ie, java.lang.ref.WeakReference. WeakHashMap is an implementation of Map interface where the memory of the value object can be reclaimed by Grabage Collector if the corresponding key is no longer referred by any section of program. This is different from HashMap where the value object remain in HashMap even if key is no longer referred. We need to explicitly call remove() method on HashMap object to remove the value so that it can be ready to be reclaimed(Provided no other section of program refers to that value object). Calling remove() is an extra overhead.

Example:

private void testWeakHashMap()
 {
    WeakHashMap<String, String> weakmap = new WeakHashMap<String, String>();
    HashMap<String, String> hmap = new HashMap<String, String>();
    String str1 = new String("string1");
    String str2 = new String("string2");
    String str3 = new String("string3");
    String str4 = new String("string4");
    String str5 = new String("string5");
    String str6 = new String("string6");
    weakhmap.put(str1, "a1");
    weakhmap.put(str2, "a1");
    weakhmap.put(str3, "a1");
    hmap.put(str4, "a1");
    hmap.put(str5, "a1");
    hmap.put(str6, "a1");

    System.out.println("\n");
   for(Entry<String, String> entry : weakhmap.entrySet())
   {
     System.out.println("WeakMap before GC:  " +entry.getKey()+"-"+entry.getValue());
   }
   System.out.println("\n");
   for(Entry<String, String> entry : hmap.entrySet())
  {
    System.out.println("HashMap before GC:  " +entry.getKey()+"-"+entry.getValue());
  }

  str2 = null;
  str3 = null;

System.gc();
System.out.println("\n");
//You can see that this Map will NOT have Key's which are nullified.. for(Entry<String, String> entry : weakhmap.entrySet())
{
  System.out.println("WeakMap after GC:  " +entry.getKey()+"-"+entry.getValue());
}
System.out.println("\n");

for(Entry<String, String> entry : hmap.entrySet())
{
   System.out.println("HashMap after GC:  " +entry.getKey()+"-"+entry.getValue());
}
}

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. On the other hand HashMap uses equals method to determine the uniqueness of the Key.

The other difference (or a consequence) is that IdentityHashMap does not use hash from object.hashCode() but uses System.identityHashCode(object). This is a major difference, because you can use IdentityHashMap for mutable objects for whose hash code changes during the “in map” time frame.

Example:

private void testIdentityHashMap()
 {
    IdentityHashMap<Object, Object> weakmap = new IdentityHashMap<Object, Object>();

Object obj1 = new Object();
Object obj2 = new Object();
String str1 = new String("hello");
String str2 = "hello";

idenMap.put(obj1, "object1");
idenMap.put(obj2, "object2");
idenMap.put(str1, "object3");
idenMap.put(str2, "object4");

System.out.println("IdentityMap size: " +idenMap.size());//returns 4 objs.
System.out.println("identityMap values: "+idenMap.values());

HashMap<Object, Object> hmap = new HashMap<Object, Object>();

Object obj3 = new Object();
Object obj4 = new Object();
String str3 = new String("hello");
String str4 = "hello";
hmap.put(obj3, "object5");
hmap.put(obj4, "object6");
hmap.put(str3, "object7");
hmap.put(str4, "object8"); //str3 and str4 keys become same here...
System.out.println("HashMap size: " +hmap.size()); //returns 3 objs
System.out.println("HashMap values: "+hmap.values());
}

EnumMap

EnumMap is a specialized implementation of Map interface  that uses enum as keys.

EnumMap gives the ORDERED COLLECTION.

Since enum can represent a type (like class or interface)  in Java and it can also override equals() and hashCode() , It can be used inside HashMap or any other collection but using  EnumMap brings implementation specific benefits which is done for enum keys, In short EnumMap is optimized Map implementation exclusively for enum keys . As per javadoc Enum is implemented using Arrays and common operations result in constant time. So if you are thinking of an high performance Map, EnumMap could be decent choice for enumeration data.

Example:

private void testEnumMap()
 {
      Map<Colors, String> enumMap = new EnumMap<Colors, String>(Colors.class);
      enumMap.put(Colors.RED, "red color");
      enumMap.put(Colors.YELLOW, "yellow color");
      enumMap.put(Colors.GREEN, "green color");

      Set<Colors> keySet = enumMap.keySet();
      for(Colors color : keySet) {
        String value = enumMap.get(color);
         System.out.println("ENUMMAP VALUE:"+value);
      }
}

public enum Colors {

     RED, YELLOW, GREEN
}

Hope I gave some basic differences between various Map implementations. I will try focus on giving more details on each Map in future posts.

Advertisements