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

4

10

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());
  }
}
Biotic answered 13/4, 2010 at 19:3 Comment(0)
M
5

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.

Meader answered 13/4, 2010 at 19:6 Comment(1)
Thanks for the comprehensive answer. Lol, I think the generic system is already complicated enough!Biotic
S
13

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

Secessionist answered 13/4, 2010 at 19:6 Comment(2)
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?Biotic
@Tarski: TreeSet was added in 1.2. Generics were added in 1.5.Milklivered
M
5

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.

Meader answered 13/4, 2010 at 19:6 Comment(1)
Thanks for the comprehensive answer. Lol, I think the generic system is already complicated enough!Biotic
B
1

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.

Bobbette answered 13/4, 2010 at 19:6 Comment(0)
H
0

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

Hypoploid answered 13/4, 2010 at 19:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.