Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Java's TreeSet not specify that its type parameter must extend Comparable?

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());
  }
}
like image 569
Tarski Avatar asked Apr 13 '10 19:04

Tarski


People also ask

Does TreeSet use comparable?

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.

Why do we get class cast exception in TreeSet Java?

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.

Why TreeSet does not allow heterogeneous objects?

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.

What is correct about the TreeSet data structure?

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.


3 Answers

TreeSet doesn't require its type parameter to be Comparable, because it can take an external Comparator for comparing non-Comparable values.

like image 161
axtavt Avatar answered Oct 04 '22 16:10

axtavt


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.

like image 23
sepp2k Avatar answered Oct 04 '22 15:10

sepp2k


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.

like image 43
Dirk Avatar answered Oct 04 '22 15:10

Dirk