Recent Posts

Monday, 1 August 2016

Collection Framework Tutorial Part 4



6. Map Interface
     The Map interface is not an extension of Collection interface. Instead the interface starts of it’s own interface hierarchy, for maintaining key-value associations. The interface describes a mapping from keys to values, without duplicate keys, by defination.

     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.

Key-Value pairs
     Key-value pairs are stored in maps.

Map interfaces
* Map implemented by HashMap and TreeMap
* SortedMap implemented by TreeMap.
* Map.Entry which describes access methods to the key-value pairs.

Implementing classes
   A number of classes implement the Map interface, including HashMap, TreeMap, LinkedHashMap, WeakHashMap, ConcurrentHashMap, and Properties. The most generally useful class is HashMap.

* java.util.HashMap is implemented with a hash table. Access time is O(1). Entries are unsorted.

* java.util.LinkedHashMap is implemented with a hash table. Access time is O(1). Entries are sorted in either entry order or order of last access, which is useful for implementing a LRU (least recently used) caching policy.

* java.util.TreeMap is implemented as a balanced binary tree. Access time is O(log N). Entries are sorted.

i. HashMap
* A HashMap contains values based on the key. It implements the Map interface.
* The underlying data structure is Hashtable.
* Duplicate keys are not allowed but values can be duplicated.
* Insertion order is not preserved and it is based on hash code of the keys.
* Heterogeneous objects are allowed for both key and value.
* null is allowed for keys(only once) and for values(any number of times).
* It is best suitable for Search operations.
     By default HashMap object is not synchronized. But we can get synchronized version by using the following method of Collections class.
public static Map synchronizedMap(Map m1)

Constructors
1. HashMap m=new HashMap();
     Creates an empty HashMap object with default initial capacity 16 and default fill ratio "0.75".

2. HashMap m=new HashMap(int initialcapacity);

3. HashMap m =new HashMap(int initialcapacity, float fillratio);

4. HashMap m=new HashMap(Map m);



E.g
package com.ashok.collections;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MyHashMap {
   public static void main(String[] args) {
      HashMap hMap = new HashMap();
      hMap.put("Ashok", 500);
      hMap.put("Vinod", 800);
      hMap.put("Dillesh", 700);
      hMap.put("Naresh", 500);
      System.out.println(hMap);
      System.out.println(hMap.put("Ashok", 1000));
      Set s = hMap.keySet();
      System.out.println(s);
      Collection c = hMap.values();
      System.out.println(c);
      Set s1 = hMap.entrySet();
      System.out.println(s1);
      Iterator itr = s1.iterator();
      while (itr.hasNext()) {
         Map.Entry m1 = (Map.Entry) itr.next();
         System.out.println(m1.getKey() + "......" + m1.getValue());
         if (m1.getKey().equals("Ashok")) {
            m1.setValue(1500);
         }
      }
      System.out.println(hMap);
   }
}

Output

{Ashok=500, Dillesh=700, Vinod=800, Naresh=500}
500
[Ashok, Dillesh, Vinod, Naresh]
[1000, 700, 800, 500]
[Ashok=1000, Dillesh=700, Vinod=800, Naresh=500]
Ashok......1000
Dillesh......700
Vinod......800
Naresh......500
{Ashok=1500, Dillesh=700, Vinod=800, Naresh=500}
ii. LinkedHashMap
     LinkedHashMap will keep the order in which the elements are inserted into it. If you will be adding and removing elements a lot, it will be better to use HashMap, because LinkedHashMap will be slower to do those operations. But, you can iterate faster using LinkedHashMap. So, if you will be iterating heavily, it may be a good idea to use this. It is exactly same as HashMap except the following differences
E.g
package com.ashok.collections;

import java.util.Collection;
import java.util.LinkedHashMap ;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MyHashMap {
   public static void main(String[] args) {
      LinkedHashMap hMap = new LinkedHashMap ();
      hMap.put("Ashok", 500);
      hMap.put("Vinod", 800);
      hMap.put("Dillesh", 700);
      hMap.put("Naresh", 500);
      System.out.println(hMap);
      System.out.println(hMap.put("Ashok", 1000));
      Set s = hMap.keySet();
      System.out.println(s);
      Collection c = hMap.values();
      System.out.println(c);
      Set s1 = hMap.entrySet();
      System.out.println(s1);
      Iterator itr = s1.iterator();
      while (itr.hasNext()) {
         Map.Entry m1 = (Map.Entry) itr.next();
         System.out.println(m1.getKey() + "......" + m1.getValue());
         if (m1.getKey().equals("Ashok")) {
            m1.setValue(1500);
         }
      }
      System.out.println(hMap);
   }
}

Output

{Ashok=500, Vinod=800, Dillesh=700, Naresh=500}
500
[Ashok, Vinod, Dillesh, Naresh]
[1000, 800, 700, 500]
[Ashok=1000, Vinod=800, Dillesh=700, Naresh=500]
Ashok......1000
Vinod......800
Dillesh......700
Naresh......500
{Ashok=1500, Vinod=800, Dillesh=700, Naresh=500}
iii. IdentityHashMap
     It is exactly same as HashMap except the following differences
* In the case of HashMap JVM will always use ".equals()" method to identify duplicate keys, which is meant for content comparision.
* But in the case of IdentityHashMap JVM will use == (double equal operator) to identify duplicate keys, which is meant for reference comparision.
E.g
package com.ashok.collections;

import java.util.Map;
import java.util.HashMap;
import java.util.IdentityHashMap;

public class MyIdentityHashMap {
   public static void main(String[] args) {
      Map hashmapObject = new HashMap();
      Map identityObject = new IdentityHashMap();

      hashmapObject.put(new String("key"), "Ashok");
      hashmapObject.put(new String("key"), "Vinod");

      identityObject.put(new String("identityKey"), "Ashok");
      identityObject.put(new String("identityKey"), "Vinod");

      System.out.println("HashMap after adding key :" + hashmapObject);
      System.out.println("IdentityHashMap after adding key :" + identityObject);
   }
}

Output
HashMap after adding key :{key=Vinod}
IdentityHashMap after adding key :{identityKey=Ashok, identityKey=Vinod}
iv. WeakHashMap
     It is exactly same as HashMap except the following differences
* In the case of normal HashMap, an object is not eligible for GC even though it doesn't have any references if it is associated with HashMap. That is HashMap dominates garbage collector.

* But in the case of WeakHashMap if an object does not have any references then it's always eligible for GC even though it is associated with WeakHashMap that is garbage collector dominates WeakHashMap. E.g
package com.ashok.collections;

import java.util.HashMap;

public class MyHashMap {
   public static void main(String[] args) throws Exception {
      HashMap map = new HashMap();
      MyKey key = new MyKey();
      map.put(key, "Ashok");
      System.out.println(map);
      key = null;
      System.gc();
      Thread.sleep(2000);
      System.out.println(map);
   }
}

class MyKey {
   public String toString() {
      return "Key is ";
   }

   public void finalize() {
      System.out.println("finalize() method called");
   }
}

Output
{Key is =Ashok}
{Key is =Ashok}
package com.ashok.collections;

import java.util.WeakHashMap;

public class MyWeakHashMap {
   public static void main(String[] args) throws Exception {
      WeakHashMap map = new WeakHashMap();
      MyKey key = new MyKey();
      map.put(key, "Ashok");
      System.out.println(map);
      key = null;
      System.gc();
      Thread.sleep(2000);
      System.out.println(map);
   }
}

class MyKey {
   public String toString() {
      return "Key is ";
   }

   public void finalize() {
      System.out.println("finalize() method called");
   }
}

Output
{Key is :=Ashok}
finalize() method called
{}
v. SortedMap
* SortedMap is the child interface of Map.
* If we want to represent a group of key-value pairs according to some sorting order of keys then we should go for SortedMap.
* Sorting is possible only based on the keys but not based on values.
* It defines the following 6 specific methods.
1. Comparator comparator( )
     Produces the comparator used for this Map, or null for natural ordering.

2. Object firstKey( )
     Produces the lowest key.

3. Object lastKey( )
     Produces the highest key.

4. SortedMap subMap(fromKey, toKey)
     Produces a view of this Map with keys from fromKey, inclusive, to toKey, exclusive.

5. SortedMap headMap(toKey)
     Produces a view of this Map with keys less than toKey.

6. SortedMap tailMap(fromKey)
     Produces a view of this Map with keys greater than or equal to fromKey.

vi. TreeMap
* The underlying data structure is RED-BLACK Tree.
* Duplicate keys are not allowed but values can be duplicated.
* Insertion order is not preserved and all entries will be inserted according to some sorting order of keys.
* If we are depending on default natural sorting order keys should be homogeneous and Comparable otherwise we will get ClassCastException.
* If we are defining our own sorting order by Comparator then keys can be heterogeneous and non Comparable.
* There are no restrictions on values they can be heterogeneous and non Comparable.
* For the empty TreeMap as first entry null key is allowed but after inserting that entry if we are trying to insert any other entry we will get NullPointerException.
* For the non empty TreeMap if we are trying to insert an entry with null key we will get NullPointerException.
* There are no restrictions for null values.

Constructors
1. TreeMap t=new TreeMap();
     For default natural sorting order.

2. TreeMap t=new TreeMap(Comparator c);
     For customized sorting order.

3. TreeMap t=new TreeMap(SortedMap m);
     TreeMap t=new TreeMap(Map m); E.g
package com.ashok.collections;

import java.util.TreeMap;
 
public class MyTreeMap {
   public static void main(String[] args) {
      TreeMap employees = new TreeMap();

      employees.put("Ashok", 87);
      employees.put("Vinod", 34);
      employees.put("Dillesh", 42);
      employees.put("Thiru", 29);
      employees.put("Naresh", 95);
       
      System.out.println(employees);
   }
}
Output
{Ashok=87, Dillesh=42, Naresh=95, Thiru=29, Vinod=34}

Next Tutorial  Collection Framework Tutorial Part 5

Previous Tutorial  Collection Framework Tutorial Part 3

No comments:

Post a Comment