it should be instead of because if E is
comparable, the children of E must be comparable whereas the parents
of E may be not.
Comparator doesn't rely on Comparable objects.
It is even often used as an alternative or a complement.
In fact, this constructor
public TreeSet(Comparator<? super E> comparator) {...}
could have been :
public TreeSet(Comparator<E> comparator) {... }
But by specifying a lower bounded wildcard, JDK developers provided more flexibility for client classes by allowing the Comparator to be interoperable with both current class instances and parent class instances. In some cases, it may make sense.
Now this :
public TreeSet(Comparator<? extend E> comparator) {
cannot be valid as it means that you may finish with a compare() method that specifies subclass type as parameters .
But elements of the Set may contain instances of a specific subclass but not only.
Imagine this code :
TreeSet<CharSequence> set = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
...
}
});
set.add("string");
set.add(new StringBuilder());
...
I want compare Strings but the Set could contain String instances but also any subclass of CharSequence such as StringBuilder, CharBuffer, etc...
And if CharSequence was not abstract, it could also contain instances of them.
With this example, we understand that conceptually Comparator<? extend E> is wrong.