WeakHashMap

WeakHashMap

It is exactly same as HashMap, except the following difference.

In the case of HashMap, an object is not eligible for garbage, if it is associated with HashMap, even though it doesn’t contain any external reference. i.e HashMap dominates garbage collector. But in the case of WeakHashMap, if an object is not having any external references, then it is always used for garbage, even though it is associated WeakHashMap i.e garbage collector dominates WeakHashMap.

Garbage Example

Temp.java

package com.narayanatutorial.collections.weakhashmap;

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

	public String toString()
    {
     return "temp" ;
    }
}

HashMapGarbageDemo.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.HashMap;


public class HashMapGarbageDemo {
	public static void main(String[] args) throws InterruptedException {
		HashMap<Temp, String> m = new HashMap<Temp, String>();
		Temp t = new Temp();
		m.put(t, "narayana");
		System.out.println("HashMap before garbage called::"+m);
		t = null;
		System.out.println("Garbage Called..");
		System.gc();
		Thread.sleep(5000);
		System.out.println("HashMap after garbage called:"+m);
		
	}
}

Output

HashMap before garbage called::{temp=narayana}
Garbage Called..
HashMap after garbage called:{temp=narayana}

WeakHashMapGarbageDemo.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.HashMap;
import java.util.WeakHashMap;

public class WeakHashMapGarbageDemo {
	public static void main(String[] args) throws InterruptedException {
		WeakHashMap<Temp, String> m = new WeakHashMap<Temp, String>();
		Temp t = new Temp();
		m.put(t, "narayana");
		System.out.println("WeakHashMap before garbage called::"+m);
		t = null;
		System.out.println("Garbage Called..");
		System.gc();
		Thread.sleep(5000);
		System.out.println("WeakHashMap after garbage called:"+m);
		
	}
}

Output

WeakHashMap before garbage called::{temp=narayana}
Garbage Called..
 finalize method
WeakHashMap after garbage called:{}
  • In this case temp object is x eligible for y, Because it is associated with HashMap& its demonstrate garbage collector, hence the output is[ temp= narayan;].
  • If we are replacing HashMap with WeakHashMap then temp object is eligible for garbage collectior. Hence the output is [ temp= narayana ],finalize method { }.
  • If key is not reachable,then the whole entry by default will be removed in this case we have to use WeakHashMap.

SortedMap

  • It is the child interface of Map.
  • If we want to represent the set of entries, according to some sorting order of keys, then we should go for SortedMap.
  • i.e sorting order is based on keys, but not based on values.

SortedMap interface defines the following six specific methods

  1. Object FirstKey()
  2. Object LastKey()
  3. SortedMap HeadMap ( Object key)
  4. SortedMap TailMap ( Object key )
  5. SortedMap TailMap ( Object key1, Object key2 )
  6. Comparator comparator ()

TreeSet

  • The underlying data structure is balanced tree duplicate objects are not allowed.
  • All elements will be inserted, according to some sorting order hence insertion order is not preserve.
  • Heterogeneous objects are not allow, violation leads ClassCastException.

Constructors

TreeSet t = new TreeSet ();

  • Natural sorting order.
  • Creates an empty TreeSet object where all the object will be inserted according to Natural sorting order.

TreeSet t = new TreeSet ( Comparator c )

  • Creates an empty TreeSet object, where all the elements are inserted according to customized sorting order described by Comparator object.

TreeSet t = new TreeSet (SortedSet s)

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetDemo {
	public static void main(String[] args) {
		TreeSet t = new TreeSet();
		t.add("A");
		t.add("B");
		t.add("Z");
		t.add("L");
		// t.add(new Integer(10)); // Class Casting Exception
		// t.add(null); // Null Pointer Exception
		System.out.println("TreeSet:"+t);
	}
}

Output

TreeSet:[A, B, L, Z]
  • For the empty TreeSet has first element null insertion is always possible. But after inserting null, if we are trying to insert any other element, we will get NullPointerException.
  • For the non-empty TreeSet, if we are trying to  insert null, we will get NullPointerException.

TreeSetDemo2.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetDemo2 {
	public static void main(String[] args) {
		TreeSet t = new TreeSet();
		t.add(new StringBuffer("A"));
		t.add(new StringBuffer("B"));
		t.add(new StringBuffer("Z"));
		t.add(new StringBuffer("L"));
		t.add(new Integer(10));
		System.out.println(t);
	}
}

output

Exception in thread "main" java.lang.ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable
	at java.util.TreeMap.compare(TreeMap.java:1294)
	at java.util.TreeMap.put(TreeMap.java:538)
	at java.util.TreeSet.add(TreeSet.java:255)
	at com.narayanatutorial.collections.weakhashmap.TreeSetDemo2.main(TreeSetDemo2.java:8)
  • If we are depending on natural sorting order, compulsory object should be homogeneous & comparable other wise we will get ClassCastException.
  • An object is said comparable if & only if the corresponding class implements comparable interface on the above case, StringBuffer doesn’t implement comparable. Hence we get ClassCastException.
  • String class & Wrapper classes comparable.

 

Comparable interface

  • It is present in java.lang package & contains only one method compareTo()

public int compareTo (Object obj)

  • If we are depending on natural sorting order, internally jvm calls compareTo () method to places object according to sorting order. Hence the objects should be comparable, other wise we will ClassCastException.
  • Sometimes we have to implement our own sorting order instead of natural sorting order.We can handle this requirement by using Comparator.

Note:-

Comparable meant for default natural sorting order.

Where as Comparator mean for customized sorting order.

 

Comparator interface

Object1.compareTo(Obj2)

returns
         -ve if obj1 has to come before obj2
          +ve if obj1 has to come after obj2
          O if obj1 & obj2 are equal
Ex:- 
       System.out.println("A".compareTo("Z")): // -ve
        System.out.println("Z".compareTo("K")): // +ve
         System.out.println("A".compareTo("A")): // O

This interface present in java.util package.This interface defines the following two methods.

Public int compare(Object obj1, Object Obj2)

Returns

  • -ve if obj1 has to come before obj2.
  • +ve if obj1 has to come after obj2.
  • O(Zero) if obj1& obj2 are equal.

Public boolean equals(Object  Obj) .

  • equal() method implementation is optional. Because  it is already available through inheritance from object class.

TreeSetDemoNaturalSortingOrder.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetDemoNaturalSortingOrder {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		 
        TreeSet t = new TreeSet (); 
         t.add(20); 
         t.add(0); 
         t.add(15);
         t.add(5);
         t.add(10); 
         System.out.println(t);
	}

}

Output

[0, 5, 10, 15, 20]

MycomparatorInteger.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.Comparator;

public class MycomparatorInteger implements Comparator<Object> {

	@Override
	public int compare(Object Obj1, Object Obj2) {
		// TODO Auto-generated method stub
		Integer I1 = (Integer) Obj1;
		Integer I2 = (Integer) Obj2;
		if (I1 < I2) {
			return +100;
		}
		else if (I1 > I2) {
			return -1;
		} else
			return 0;
	}
}
  • At line 1, If we are not passing, Comparator object has argument, jvm internally calls compareTo () method, which is mean for default natural sorting order (ascending order with in case output).[ 0,5,10,15,20]
  • At line 1, If we are passing, Comparator object has argument, jvm  calls our own  compare method, which is mean for default customized sorting order (descending order with in case output).[ 20,15,10,5,0]

TreeSetDemoCustomSortingOrder.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetDemoCustomSortingOrder {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       TreeSet t = new TreeSet (new MycomparatorInteger()); 
         t.add(20); 
         t.add(0); 
         t.add(15);
         t.add(5);
         t.add(10); 
         System.out.println(t);
	}
}

Output

[20, 15, 10, 5, 0]

If we are implementing compare method as follow then corresponding outputs are

MycomparatorIntegerDemo.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.Comparator;

public class MycomparatorIntegerDemo implements Comparator<Object> {

	@Override
	public int compare(Object Obj1, Object Obj2) {
		// TODO Auto-generated method stub
		Integer I1 = (Integer) Obj1;
		Integer I2 = (Integer) Obj2;

		 return I1.compareTo(I2); //[0,5,10,15,20]
		// return I2.compareTo(I1); //[20,15,10,5,0]
	    //return O ; // insert element present & all the remaining elements treated duplicates[20]
	}
}

Write a program to insert String objects into the TreeSet, where the sorting order is reverse of alphabetical order.

MyComparatorString.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.Comparator;

public class MyComparatorString implements Comparator{

	@Override
	public int compare(Object Obj1, Object Obj2) {
		// TODO Auto-generated method stub
		String s1 = Obj1.toString();
	    String s2 = (String)Obj2;
	    return s2.compareTo(s1);
	}
  
}

TreeSetDemoReverseSortingOrderString.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetDemoReverseSortingOrderString {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       TreeSet t = new TreeSet (new MyComparatorString()); 
       t.add("A");
       t.add("Z");
       t.add("K");
       t.add("B");
       System.out.println(t);
	}
}

Output

[Z, K, B, A]

Write a program to insert StringBuffer Object into the TreeSet, where sorting order is alphabetical order.

MyComparatorStringBufferToString.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.Comparator;

public class MyComparatorStringBufferToString implements Comparator{

	@Override
	public int compare(Object Obj1, Object Obj2) {
		// TODO Auto-generated method stub
		String s1 = Obj1.toString();
	    String s2 = Obj2.toString();
	    return s1.compareTo(s2);
	}
  
}

TreeSetStringBufferAlphaOrder.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetStringBufferAlphaOrder {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet t = new TreeSet (new MyComparatorStringBufferToString());
        t.add(new StringBuffer("A")); 
         t.add(new StringBuffer("B")); 
         t.add(new StringBuffer("Z"));
         t.add(new StringBuffer("L")); 
         System.out.println(t); 
	}

}

Output

[A, B, L, Z]
  • If we are defining  our own sorting by Comparator then the objects needn’t be comparable (Homogeneous).
  • Write a program, to insert String & StringBuffer object into TreeSet, where the  sorting order is increasing length order. If two objects having the same length then consider their alphabetical order.

Write a program for heterogeneous sorting order

MyComparatorHeterogeneous.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.Comparator;

public class MyComparatorHeterogeneous implements Comparator {

	@Override
	public int compare(Object Obj1, Object Obj2) {
		// TODO Auto-generated method stub
		String s1 = Obj1.toString();
		String s2 = Obj2.toString();
		int l1 = s1.length();
		int l2 = s2.length();
		if (l1 < l2)
			return -1;
		else if (l1 > l2)
			return +1;
		else
			return s1.compareTo(s2);
	}

}

TreeSetHeterogeneousMyComparator.java

package com.narayanatutorial.collections.weakhashmap;

import java.util.TreeSet;

public class TreeSetHeterogeneousMyComparator {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		  TreeSet t = new TreeSet (new MyComparatorHeterogeneous());
		         t.add("A");
		         t.add(new StringBuffer("ABC"));
		         t.add(new StringBuffer("AA"));   
		         t.add("XX");
		         t.add("ABCD");
		         t.add("A");
		        System.out.println(t);
	}

}

Output

[A, AA, XX, ABC, ABCD]

  1. If we are defining our own sorting order by Comparator, then Objects need not be homogeneous.
  2. For defined comparable classes, natural sorting order is already available. If we want to define our own sorting order we can implement by using comparable.
  3. For predefined non comparable classes, there is no default natural sorting order. If we want define sorting, compulsory we should go for Comparator interface.
  4. Here comparable is not the choice,because we can’t modify source code of predefined classes.
  5. For our own classes, to define natural sorting order, we can go for comparable interface.
  6. if we want to change the sorting , then we can go for Comparator.
import java.util.*;
Class Employee Implements Comparable
{
         int eno;
         Employee (int eno)
        {
        this.eno.eno;
        }
        Public String toString()
        {
         return " e" +eno;
       }
        Public int compareTo(Object 01)
        {
        int eno1= this.eno;
        int eno2= ((employee)01).eno;
        if (eno1<eno2)   
         {
            return -1;
         }
         else if(eno1>eno2)
          {
             return 1;
          }
          else return 0;
          }
}
Class compcomp
{
 Public int Compare(object Obj1, Object Obje2) 
            { 
              Employee e1 = new Employee(100);    
              Employee e2 = new Employee(500);
              Employee e3 = new Employee(700);
              Employee e4 = new Employee(200);
             TreeSet t= new TreeSet();
             t.add(e1);
             t.add(e2);
             t.add(e3);
             System.out.println(t);
              TreeSet t = new TreeSet (new MyComparator());
                t1.add(e1);
                t1.add(e2);
                t1.add(e3);
                t1.add(e4);
                System.out.println(t);
               }
}


Class MyComparator implements Comparator
 {
 Public int Compare(object Obj1, Object Obje2)
      {
        Integer I1 = ((Employee)Obj1).eno;
        Integer I1 = ((Employee)Obj1).eno;
         return I2.compareTo(I10;
        }
}

Comparison between Comparable and Comparator

Comparable

  1. Present in java.lang package.
  2. Contains only one method public int compareTo(Obj2).
  3. To define natural sorting.
  4. String class and wrapper classes  implemented this interface.

Comparator

  1. Present in java.util package.
  2. Contains two methods ( Object Obj1, Object Obj2).
  3. To redefine customized sorting order.
  4. No,It isn’t marker interface.

Comparison between Set implemented classes

PropertyHashSetLinkedHashSetTreeSet
Data Structure HasTable HashTable
LinkedList.
Balance Tree
Insertion order Not preserve. Preserve Not preserve
Sorting order Not preserve Not preserve Preserve
Duplicate Objects No No No

Heterogeneous
Allowed Allowed Not allowed otherwise ClassCastException
Null acceptance Allowed Allowed[once]. For empty TreeSet add first element allowed. In other cases, we will get NullPointerException

The Author

Narayanaswamy

Hello! I am Narayanaswamy founder and admin of narayanatutorial.com. I have been working in IT industry more than 7 years. NarayanaTutorial is my web technologies blog. My specialties are Java / J2EE, Spring, Hibernate, Struts, Webservices, PHP, Oracle, MySQL, SQLServer, Web Hosting and Website Development. I am a self learner and passionate about training and writing. I am always trying my best to share my knowledge through my blog.

Leave a Reply