e.g. The code below throws a ClassCastException when the second Object is added to the TreeSet. Couldn't TreeSet have been written so that the type parameter can only be a Comparable type? i.e. TreeSet would not compile because Object is not Comparable. That way generics actually do their job - of being typesafe.
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String [] args) {
TreeSet<Object> t = new TreeSet<Object>();
t.add(new Object());
t.add(new Object());
}
}
The elements in TreeSet must be of a Comparable type. String and Wrapper classes are Comparable by default. To add user-defined objects in TreeSet, you need to implement the Comparable interface.
This error is thrown by TreeSet because TreeSet is used to store elements in sorted order and if the specified element cannot be compared with the elements currently in the set then TreeSet won't be able to store elements in sorted order and hence, TreeSet throws class cast exception.
TreeSet does not allow to insert heterogeneous objects because it must compare objects to determine sort order. TreeSet is not synchronized. If multiple threads access a hash set concurrently, and at least one of the threads modifies the set, it must be synchronized externally. Use Collections.
The data structure for the TreeSet is TreeMap; it contains a SortedSet & NavigableSet interface to keep the elements sorted in ascending order and navigated through the tree. As soon as we create a TreeSet, the JVM creates a TreeMap to store the elements in it and performs all the operations on it.
TreeSet
doesn't require its type parameter to be Comparable
, because it can take an external Comparator
for comparing non-Comparable
values.
If the type would have to be Comparable, you couldn't create a TreeSet with a non-comparable type and a Comparator (which you can as it is now).
One way to fix this while still being type-safe would have been to have two classes: one with a comparable type parameter and one with a non-comparable type parameter and no default constructor (only the constructor that takes a Comparator), but I suppose the java devs didn't want to introduce two classes that basically did the same thing (though one could easily be implemented as a wrapper around the other).
Another (and arguably cleaner way) would be to extend the type system so that certain constructors only exist when used with certain type parameters (i.e. the default constructor only exists if the type parameter is comparable), but I suppose that would have made the generic system too complex for java.
That's because the value does not necessarily have to implement Comparable
. You can pass the set a Comparator
object explicitly, in which case the element type does not need to be a Comparable
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With