Reputation: 14471
I was working with TreeSet
and found a ClassCastException
while calling TreeSet#add()
method.
Code:
public class Testing {
public static void main(String[] args) {
TreeSet<Testing> ts = new TreeSet<>();
ts.add(new Testing());
}
}
Output:
Exception in thread "main" java.lang.ClassCastException: Testing cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at Testing.main(Testing.java:13)
Clearly it's because TreeSet
is an ordered collection and it needs Comparable
objects for ordering them, so why not declare its type as
public class TreeSet<E extends Comparable<E>>
and do the checking during compile time instead of throwing exception at runtime?
Upvotes: 3
Views: 332
Reputation: 100209
As was mentioned in other answers, TreeSet
keys could be not Comparable
if custom Comparator
is specified. It still would be possible to enforce compile-time check for your case. Suppose that we make the default constructor private and provide a static factory method instead:
public class TreeSet<E> {
private TreeSet() {...}
public static <E extend Comparable<? super E>> TreeSet<E> newSet() {
return new TreeSet<>();
}
}
This way you would be forced to use TreeSet.newSet()
and compile-time type checking would fail if you assign it to TreeSet<Testing>
and Testing
is not comparable. Why it was not done? Because generics appeared in Java 1.5 only, while TreeSet
appeared in Java 1.2, is it was not an issue these times. Now we have to deal with backwards compatibility.
Upvotes: 1
Reputation: 1582
The way it is implemented, you can order items that cannot decide for themselves if they should be ordered in a higher or lower spot than the "other" item.
Take a real life example: You have a beauty contest. If you ask one of the girls if she is more beautiful than the one next to her, she will say yes. You cannot put them in an order just by asking them. So you need somebody else to be responsible for the ordering, the Comparator.
This allows you to order items that don't have the possibility to compare themselves with another item.
Upvotes: 0
Reputation: 393811
A TreeSet
's element doesn't have to implement Comparable
, since you can pass a Comparator
to one of TreeSet
's constructors in order to impose an ordering for elements that don't implement Comparable
(or for elements that do implement Comparable
when you want to use an ordering other than the natural ordering defined by Comparable
).
Upvotes: 7