Search This Blog

Friday, December 21, 2012

Exploring treeset

Exporing treeset in following case study  :

Step 1 :  Just write a simple program which has main method as  below:
package com.examples.coll.set.treeset;

import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {

    public static void main(String args[]) {
        TestTreeSet t = new TestTreeSet();
        Set treeSet = new TreeSet(); // Declare Treeset of type intree
        intree tree1 =t.new intree("tree1");
        treeSet.add(tree1);// added one object into treeset
        for (intree t1 : treeSet) {
            t1.show(); // To print name
        }
    }
    class intree { // inner class , object of this class is added into treeset
        String name;
        intree(String name){ //Constructor
            this.name = name;
        }
        void show(){
            System.out.print(name); // to print name
        }
    }
}

Step 2 : Compile this program ... no compilation error ...hmmmm we are good to go then .
Let's try to run this ...
java TestTreeSet
Output : tree1

wow it is simple ... we have successfully added one object of "intree" into treeset. it means one object can be easily added into treeset and we will definatly get successfull result .

Step 3 : Not let's go to next step further , try to add some more objects of same type into tree..

package com.examples.coll.set.treeset;

import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {

    public static void main(String args[]) {
        TestTreeSet t = new TestTreeSet();
        Set treeSet = new TreeSet(); // Declare Treeset of type intree
        intree tree1 =t.new intree("tree1");
        intree tree2 =t.new intree("tree2");
        intree tree3 =t.new intree("tree3");
        treeSet.add(tree1);// added 1st object into treeset
        treeSet.add(tree2);// added 2nd object into treeset
        treeSet.add(tree3);// added 3rd object into treeset
        for (intree t1 : treeSet) {
            t1.show(); // To print name
        }
    }
    class intree { // inner class , object of this class is added into treeset
        String name;
        intree(String name){ //Constructor
            this.name = name;
        }
        void show(){
            System.out.print(name); // to print name
        }
    }
}

Run step 2 first to run the program :

Ouptut :
Exception in thread "main" java.lang.ClassCastException: com.examples.coll.set.treeset.TestTreeSet$intree cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(Unknown Source)
    at java.util.TreeSet.add(Unknown Source)
    at com.examples.coll.set.treeset.TestTreeSet.main(TestTreeSet.java:28)


Grrrrrrrrrrr error ..... something worng but what :-) .. let me go to api what jdk say about this ..
searching apiiiiiiii wait.........ohh got one rule and root cause of this error :



Rule : A TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal.

And as per above rule let us  change the program ....

Step 4 : Impelemtes comparable interface and compareTo into the class of which object need to add into treeset as shown below .

package com.examples.coll.set.treeset;

import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {

    public static void main(String args[]) {
        TestTreeSet t = new TestTreeSet();
        Set treeSet = new TreeSet(); // Declare Treeset of type intree
        intree tree1 =t.new intree("tree1");
        intree tree2 =t.new intree("tree2");
        intree tree3 =t.new intree("tree3");
        treeSet.add(tree1);// added 1st object into treeset
        treeSet.add(tree2);// added 2nd object into treeset
        treeSet.add(tree3);// added 3rd object into treeset
        for (intree t1 : treeSet) {
            t1.show(); // To print name
        }
    }
    class intree implements Comparable{ // inner class , object of this class is added into treeset
        String name;
        intree(String name){ //Constructor
            this.name = name;
        }
        void show(){
            System.out.print(name); // to print name
        }
        @Override
        public int compareTo(Object arg0) {
            return 0;
        }
    }
}

Run step 2 first to run the program :
Ouput  : tree1

hurreyy.... successfully ran this program ... but .... wait ... I was expecting three records .. and it is showing only one ... grrrrrrrrrrr something wrong again but what ....let me go to api againn what jdk says about this ..
searching apiiiiiiii wait.........ohh got the problem .. compareTo method is returning always "0" ...h,, new rule :
Ruel2 : During add of another object into tree set it calls to compareTo method and should check object equality. if it returns false or "0" it will not add object into treeset.
Here all comparison returns "0" means all other objects can not be added and treeset contains only first one ..hence resulted as "tree1".   

Step 5 :  Let's modify compareTo method in following way to resolve above problem :

package com.examples.coll.set.treeset;

import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {

    public static void main(String args[]) {
        TestTreeSet t = new TestTreeSet();
        Set treeSet = new TreeSet(); // Declare Treeset of type intree
        intree tree1 =t.new intree("tree1");
        intree tree2 =t.new intree("tree2");
        intree tree3 =t.new intree("tree3");
        treeSet.add(tree1);// added 1st object into treeset
        treeSet.add(tree2);// added 2nd object into treeset
        treeSet.add(tree3);// added 3rd object into treeset
        for (intree t1 : treeSet) {
            t1.show(); // To print name
        }
    }
    class intree implements Comparable{ // inner class , object of this class is added into treeset
        String name;
        intree(String name){ //Constructor
            this.name = name;
        }
        void show(){
            System.out.print(name); // to print name
        }
        @Override
        public int compareTo(Object arg0) {
            if (name.equals(((intree)arg0).name)) {
                return 0;
            }
            return 1;
        }
    }
}

Run the step 2 again ..
Output : tree1tree2tree3

hurrayyyyy we got the expected result here . It means now if name string matches then object will not add into treeset otherwise it will.

Step 6 : Let's try how can we avoid null object into treeset ..

change compareTo as below :

package com.examples.coll.set.treeset;

import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {

    public static void main(String args[]) {
        TestTreeSet t = new TestTreeSet();
        Set treeSet = new TreeSet(); // Declare Treeset of type intree
        intree tree1 =t.new intree("tree1");
        intree tree2 =t.new intree("tree2");
        intree tree3 =t.new intree("tree3");
        intree tree4 = t.new intree(null); // line 26
        treeSet.add(tree1);// added 1st object into treeset
        treeSet.add(tree2);// added 2nd object into treeset
        treeSet.add(tree3);// added 3rd object into treeset
        treeSet.add(tree4); // line 31
        for (intree t1 : treeSet) {
            t1.show(); // To print name
        }
    }
    class intree implements Comparable{ // inner class , object of this class is added into treeset
        String name;
        intree(String name){ //Constructor
            this.name = name;
        }
        void show(){
            System.out.print(name); // to print name
        }
        @Override
        public int compareTo(Object arg0) {
            if (name == null || ((intree)arg0).name == null)
            {
                return 1; // or return 0 @ line 61
            }
            else if (name.equals(((intree)arg0).name)) {
                return 0;
            }
            return 1;
        }
    }
}

Observe line 26 , 31 and 61
run the step 2 again :

Ouput : tree1tree2tree3null

And if we do the change at line 61 to "return 0" it will never allow to add null..and output in this case ..

Output : tree1tree2tree3

Rule 3 : null can be allowd into treeset but it is based on implementation . put a check for null to avoid null pointer and handle it gracefully . which can be done by compareTo.

Rule 4 :  Remeber if only one object is adding into treeset.. then call will never go compareTo method . It also happens if more than one object need to add into treeset. Please check step 1.

Cheers

Kapil


No comments:

Post a Comment

Thanks for your comment, will revert as soon as we read it.

Popular Posts