Implement Comparable for a TreeSet

The first example below shows a common mistake when an object is added to a set. Because every element in a set much be unique, any object must be compared with the objects in the set already before it is added.

1. Common Mistake of Comparable Interface

First take a took at the following code which create 3 dogs and add those dogs to a TreeSet.

import java.util.TreeSet;

class Dog {
    int size;
    Dog(int s) {
        size = s;
    }
}

public class ImpComparableWrong {

    public static void main(String[] args) {
        TreeSet<Integer> i = new TreeSet<Integer>();
        TreeSet<Dog> d = new TreeSet<Dog>();
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(1));

        i.add(1);
        i.add(2);
        i.add(3);

        System.out.println(d.size() + " " + i.size());
    }
}

The output is:

run:
Exception in thread “main” java.lang.ClassCastException: Dog cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(TreeMap.java:542)
at java.util.TreeSet.add(TreeSet.java:238)
at ImpComparableWrong.main(ImpComparableWrong.java:17)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

The reason is that Class Dog needs to implement Comparable in order for a TreeSet (which keeps its elements sorted) to be able to contain Dog objects. The added object cannot be compared with the elements currently in the set, the add(Object) call throws a ClassCastException. To make an object comparable, user-defined class must implement the Comparable interface.

2. Solution for implementing Comparable for a TreeSet

The following is the code corrected (which implements Comparable):


import java.util.TreeSet;

class Dog implements Comparable<Dog> {

    int size;

    Dog(int s) {
        size = s;
    }

    public int compareTo(Dog o) {
        return size - o.size;
    }
}

public class ImpComparable {

    public static void main(String[] args) {

        TreeSet<Dog> d = new TreeSet<Dog>();
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(1));

        TreeSet<Integer> i = new TreeSet<Integer>();
        i.add(1);
        i.add(2);
        i.add(3);

        System.out.println(d.size() + " " + i.size());
    }
}

Output:


run:
2 3
BUILD SUCCESSFUL (total time: 0 seconds)

Related Articles:

Category: Collections  
  • Mohammed

    Very Useful…

  • Ruchika

    Thanks.. was looking for the same thing