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 String
s 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.