2

When implementing my own data structures which require a comparable type I've always done so like this:

public class ComparableCollection<E extends Comparable<E>> { ... }

This obviously enforces the comparable constraint at compile time. But I've been a student for the last couple years and have somehow overlooked the fact that the Java implementations for collections that enforce a comparable type do not do so at compile time but rather at runtime by possibly throwing a ClassCastException while adding an element; e.g.:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, ... { ... }

TreeSet is backed by a NavigableMap which, if it's Comparator is null, attempts to cast the key like so:

Comparable<? super K> k = (Comparable<? super K>) key;

Now, if the type being inserted isn't comparable a ClassCastException is thrown.

What are the real benefits of this design over enforcing the constraint at compile time?

ChiefTwoPencils
  • 13,548
  • 8
  • 49
  • 75
  • See also http://stackoverflow.com/questions/13890542/creating-a-treeset-with-a-non-comparable-class-why-a-run-time-exception-rather. Elements in a `TreeSet` do not need to be comparable, you can give explicitely a comparator. – Tunaki Jun 28 '16 at 19:19
  • @Tunaki, amazing how something makes a lot more sense when you get out of your own head. That just makes way too much sense. Having a duh moment now. – ChiefTwoPencils Jun 28 '16 at 19:24

2 Answers2

1

The benefit is that you can then use TreeSet with objects that do not implement Comparable but for which you can provide a Comparator.

For more about the differences between Comparable an Comparator, see: Java : Comparable vs Comparator

Community
  • 1
  • 1
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
0

You can not control what objects are getting inserted in Collection at Compile time always. Its more flexible to allow dynamic definition of the Collection.

Amit Mahajan
  • 895
  • 6
  • 34