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() + &quot; &quot; + 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() + &quot; &quot; + i.size());
    }
}

Output:

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

3. Comparator vs. Comparable

Check out the comparision and figure out when to use which.

Category >> Collections  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Ruchika on 2010-11-18

    Thanks.. was looking for the same thing

  2. Mohammed on 2012-3-21

    Very Useful…

  3. asdf on 2015-11-17

    asdfg

  4. infoj on 2016-6-3

    By default elements are stored in TreeSet using natural ordering. If you want to sort using different order then you need to provide your own comparator.

    If you want to sort a TreeSet of Strings in descending order there is an example here – http://netjs.blogspot.com/2015/10/how-to-sort-elements-in-different-order-tree-set-java.html

  5. Yishagerew lulie on 2016-9-23

    There are actually various ways to implement a comparator inside a class without implementing the comparator interface, here is one.

    class Dog{
    // other sections of the code ommitted
    public static final Comparator dogSize = new Comparator(){
    @Override
    public int compareTo(Dog o) {
    return size - o.size;
    }
    }
    }

    And in the main method, you can use it as


    TreeSet d = new TreeSet(Dog.dogSize);

Leave a comment

*