Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does TreeSet throw a ClassCastException?

I am trying to add two 'Employee' objects to a TreeSet:

Set<Employee> s = new TreeSet<Employee>();
s.add(new Employee(1001));
s.add(new Employee(1002));

But it throws a ClassCastException:

Exception in thread "main" java.lang.ClassCastException: Employee cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(TreeMap.java:542)
    at java.util.TreeSet.add(TreeSet.java:238)
    at MyClient.main(MyClient.java:9)

But if I add only one object to the TreeSet:

Set<Employee> s = new TreeSet<Employee>();
s.add(new Employee(1001));

Or if I use a HashSet instead:

Set<Employee> s = new HashSet<Employee>();
s.add(new Employee(1001));
s.add(new Employee(1002));

Then it is successful. Why does the exception happen and how do I fix it?

like image 374
Rais Alam Avatar asked Apr 11 '13 07:04

Rais Alam


People also ask

What causes a ClassCastException?

ClassCastException is a runtime exception raised in Java when we try to improperly cast a class from one type to another. It's thrown to indicate that the code has attempted to cast an object to a related class, but of which it is not an instance.

What code will cause a ClassCastException to be thrown?

Class ClassCastException Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. For example, the following code generates a ClassCastException : Object x = new Integer(0); System.

How do you avoid ClassCastException?

To prevent the ClassCastException exception, one should be careful when casting objects to a specific class or interface and ensure that the target type is a child of the source type, and that the actual object is an instance of that type.

What is ClassCastException What is the solution for that?

It is a runtime exception that occurs when the application code attempts to cast an object to another class of which the original object is not an instance. For example, a String object cannot be cast to an Integer object and attempting to do so will result in a ClassCastException .


2 Answers

Either Employee has to implement Comparable, or you need to provide a comparator when creating the TreeSet.

This is spelled out in the documentation for SortedSet:

All elements inserted into a sorted set must implement the Comparable interface (or be accepted by the specified comparator). Furthermore, all such elements must be mutually comparable: e1.compareTo(e2) (or comparator.compare(e1, e2)) must not throw a ClassCastException for any elements e1 and e2 in the sorted set. Attempts to violate this restriction will cause the offending method or constructor invocation to throw a ClassCastException.

If you don't fulfil these requirements, the sorted set won't know how to compare its elements and won't be able to function.

like image 95
NPE Avatar answered Sep 20 '22 17:09

NPE


TreeSet requires elements to implement the Comparable interface if a custom Comparator is not set. HashSet uses the equals/hashCode contract instead.

You can add only one element into TreeSet which does not implement Comparable because it does not need to be compared with other elements.

Take a look at the TreeMap.put(K key, V value) source code and you'll clearly see the reasons behind all your questions (TreeSet is based on TreeMap, hence the source reference).

like image 41
denis.solonenko Avatar answered Sep 22 '22 17:09

denis.solonenko