views:

222

answers:

4

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());
  }
}
+12  A: 

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

axtavt
Ah thanks. I suppose there no way to specify a restriction on the no-args constructor so that it can only take Comparables? Would it have been a better design to have two classes - one that takes a Comparable type parameter and one that takes any type paramter but it's constructors must take Comparators?
Tarski
@Tarski: `TreeSet` was added in 1.2. Generics were added in 1.5.
Tom Hawtin - tackline
+3  A: 

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.

sepp2k
Thanks for the comprehensive answer. Lol, I think the generic system is already complicated enough!
Tarski
+1  A: 

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.

Dirk
A: 

You can also create a TreeSet with a Comparator as constructor parameter. Then your items do not have to be comparable.

Eric Eijkelenboom