This example shows how to fix java.lang.ClassCastException – cannot be cast to java.lang.Comparable exception while adding a key-value mapping to the TreeMap object using the put or other methods.
What is the reason for the java.lang.ClassCastException while adding mappings to the TreeMap in Java?
Let’s first see a small example of the TreeMap having the keys as objects of custom class Employee.
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 |
import java.util.TreeMap; class Employee{ private Integer id; private String name; public Employee(Integer id, String name){ this.id = id; this.name = name; } public String toString(){ return "[" + this.id + " => " + this.name + "]"; } } public class TreeMapComparableExample { public static void main(String[] args) { TreeMap<Employee, Integer> treemap = new TreeMap<Employee, Integer>(); treemap.put(new Employee(1, "Jack"), 1); } } |
The program will throw “java.lang.ClassCastException: com.javacodeexamples.collections.treemap.Employee cannot be cast to java.lang.Comparable” exception when you run it.
Output
1 2 3 |
Exception in thread "main" java.lang.ClassCastException: com.javacodeexamples.collections.treemap.Employee cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(Unknown Source) at java.util.TreeMap.put(Unknown Source) |
Now if you look at the TreeMap documentation, you will find the following text inside TreeMap constructors section.
Constructs a new, empty tree map, using the natural ordering of its keys. All keys inserted into the map must implement the Comparable interface.
Constructs a new, empty tree map, ordered according to the given comparator. All keys inserted into the map must be mutually comparable by the given comparator.
It means that the objects used as keys of the TreeMap must either implement the Comparable interface, or a custom Comparator must be provided at the TreeMap creation time. In the above example, we did neither of that and that was the reason for the ClassCastException.
How to fix java.lang.ClassCastException while using the TreeMap?
There are a couple of ways to fix this exception, either implement the Comparable interface or provide a custom comparator in the TreeMap constructor.
1. Resolve using the Comparable
The class objects used as keys of the TreeMap can implement the Comparable interface to resolve this exception 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 |
import java.util.TreeMap; //STEP 1: Implement the Comparable interface in your key custom class class Employee implements Comparable<Employee>{ private Integer id; private String name; public Employee(Integer id, String name){ this.id = id; this.name = name; } public String toString(){ return "[" + this.id + " => " + this.name + "]"; } public int getId(){ return this.id; } /* * STEP 2: Define compareTo method * This method will compare this employee object with another */ public int compareTo(Employee o) { return this.getId() - o.getId(); } } public class TreeMapComparableExample { public static void main(String[] args) { TreeMap<Employee, Integer> treemap = new TreeMap<Employee, Integer>(); treemap.put(new Employee(3, "Jack"), 3); treemap.put(new Employee(1, "Emily"), 1); treemap.put(new Employee(2, "Maria"), 2); System.out.println("TreeMap contains: " + treemap); } } |
Output
1 |
TreeMap contains: {[1 => Emily]=1, [2 => Maria]=2, [3 => Jack]=3} |
Visit Java Comparable Tutorial for more information on how to implement the Comparable interface.
2. Resolve using the Comparator
You can also provide a custom comparator for the key objects in the TreeMap constructor. In that case, the keys added to the TreeMap object will be ordered using the specified comparator object 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 |
import java.util.Comparator; import java.util.TreeMap; class Employee{ private Integer id; private String name; public Employee(Integer id, String name){ this.id = id; this.name = name; } public String toString(){ return "[" + this.id + " => " + this.name + "]"; } public int getId(){ return this.id; } } /* * STEP 1: Create a custom Comparator for Employee objects */ class EmpComparator implements Comparator<Employee>{ //STEP 2: define the compare method public int compare(Employee emp1, Employee emp2) { return emp1.getId() - emp2.getId(); } } public class TreeMapComparableExample { public static void main(String[] args) { //STEP 3: Specify the custom comparator using the TreeMap constructor TreeMap<Employee, Integer> treemap = new TreeMap<Employee, Integer>( new EmpComparator() ); treemap.put(new Employee(3, "Jack"), 3); treemap.put(new Employee(1, "Emily"), 1); treemap.put(new Employee(2, "Maria"), 2); System.out.println("TreeMap contains: " + treemap); } } |
Output
1 |
TreeMap contains: {[1 => Emily]=1, [2 => Maria]=2, [3 => Jack]=3} |
As you can see from the output, the Employee objects are automatically sorted by the specified custom comparator class.
Visit Java Comparator Tutorial for more information on how to implement the Comparator interface.
This example is a part of the Java TreeMap Tutorial with Examples.
Please let me know your views in the comments section below.
References:
Java 8 TreeMap