This example shows how to solve TreeSet java.lang.ClassCastException: cannot be cast to java.lang.Comparable exception while working with the custom class objects.
What is the reason for TreeSet java.lang.ClassCastException exception?
Let’s first see a small example of TreeSet of a custom class objects as elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import java.util.TreeSet; class Emp{ private int id; public Emp(int id){ this.id = id; } public String toString(){ return "Emp -> " + this.id; } } public class TreeSetClassCastExceptionExample { public static void main(String[] args) { TreeSet<Emp> tSetEmployees = new TreeSet<Emp>(); //this line will throw java.lang.ClassCastException tSetEmployees.add(new Emp(1)); } } |
Output
1 2 3 4 |
Exception in thread "main" java.lang.ClassCastException: com.javacodeexamples.collections.treeset.Emp cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(Unknown Source) at java.util.TreeMap.put(Unknown Source) at java.util.TreeSet.add(Unknown Source) |
In order to understand the reason for this exception, we need to look at the TreeSet documentation. Here is what it says.
A NavigableSet implementation based on a TreeMap. The elements are ordered using their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used.
So it says that the TreeSet elements are ordered using the natural ordering or a Comparator provided in the TreeSet constructor. We used a default constructor and did not provide the comparator object when we created the TreeSet object.
The natural order of the element is defined by the Comparable interface and we did not implement that either in the Emp custom class. That is the reason we got the “java.lang.ClassCastException: com.javacodeexamples.collections.treeset.Emp cannot be cast to java.lang.Comparable” exception.
How to fix java.lang.ClassCastException while working with the TreeSet?
We need to either implement the Comparable interface and define the compareTo
method in Emp custom class or provide a custom Comparator object while creating the TreeSet to solve this exception. I am going to show you both.
1. By implementing the Comparable interface
Let’s implement the Comparable interface and define the compareTo
method in the Emp class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import java.util.TreeSet; /* * Step 1. Implement the Comparable interface * in your custom class */ class Emp implements Comparable<Emp>{ private int id; public Emp(int id){ this.id = id; } public String toString(){ return "Emp -> " + this.id; } public int getId(){ return this.id; } /* * Step 2. Define the compareTo method. * This compareTo method will sort Emp objects * in ascending order according the id */ public int compareTo(Emp otherEmp) { return getId() - otherEmp.getId(); } } public class TreeSetClassCastExceptionExample { public static void main(String[] args) { TreeSet<Emp> tSetEmployees = new TreeSet<Emp>(); tSetEmployees.add(new Emp(3)); tSetEmployees.add(new Emp(2)); tSetEmployees.add(new Emp(1)); System.out.println("TreeSet Contains: " + tSetEmployees); } } |
Output
1 |
TreeSet Contains: [Emp -> 1, Emp -> 2, Emp -> 3] |
Once we implement the Comparable interface and define the compareTo
method, we will no longer get the java.lang.ClassCastException exception.
2. By providing a custom Comparator in TreeSet constructor
Another alternative is to create a custom Comparator class and provide its object in the TreeSet constructor as given below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import java.util.Comparator; import java.util.TreeSet; class Emp{ private int id; public Emp(int id){ this.id = id; } public String toString(){ return "Emp -> " + this.id; } public int getId(){ return this.id; } } /* * Step 1. Create a custom comparator class * * This Comparator will compare Emp objects and sorts * them in ascending order */ class EmpComparator implements Comparator<Emp>{ /* * Step 2. Define compare method */ public int compare(Emp e1, Emp e2) { return e1.getId() - e2.getId(); } } public class TreeSetClassCastExceptionExample { public static void main(String[] args) { /* * Step 3. Provide an object of the comparator in the * TreeSet constructor */ TreeSet<Emp> tSetEmployees = new TreeSet<Emp>( new EmpComparator() ); tSetEmployees.add(new Emp(3)); tSetEmployees.add(new Emp(2)); tSetEmployees.add(new Emp(1)); System.out.println("TreeSet Contains: " + tSetEmployees); } } |
Output
1 |
TreeSet Contains: [Emp -> 1, Emp -> 2, Emp -> 3] |
As we can see from the output, we have no longer received the ClassCastException and all Emp objects were sorted in the ascending order by the custom comparator.
This example is a part of the Java TreeSet Tutorial with Examples.
Please let me know your views in the comments section below.
References:
Java 8 TreeSet