Q:

Why is TreeSet declared TreeSet instead of TreeSet>

I was working with TreeSet and found a ClassCastException while calling TreeSet#add() method.
Code:
public class Testing {
    public static void main(String[] args) {
        TreeSet<Testing> ts = new TreeSet<>();
        ts.add(new Testing());
    }
}

Output:
Exception in thread "main" java.lang.ClassCastException: Testing cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1290)
    at java.util.TreeMap.put(TreeMap.java:538)
    at java.util.TreeSet.add(TreeSet.java:255)
    at Testing.main(Testing.java:13)

Clearly it's because TreeSet is an ordered collection and it needs Comparable objects for ordering them, so why not declare its type as
public class TreeSet<E extends Comparable<E>>

and do the checking during compile time instead of throwing exception at runtime?

A:

A TreeSet's element doesn't have to implement Comparable, since you can pass a Comparator to one of TreeSet's constructors in order to impose an ordering for elements that don't implement Comparable (or for elements that do implement Comparable when you want to use an ordering other than the natural ordering defined by Comparable).

