Home > Back-end >  Why does the Java PriorityQueue implementation use Comparator<? super E> and not simply Compar
Why does the Java PriorityQueue implementation use Comparator<? super E> and not simply Compar

Time:03-19

The Java PriorityQueue source code defined in jdk8 uses a comparator defined like this

    /**
     * The comparator, or null if priority queue uses elements'
     * natural ordering.
     */
    private final Comparator<? super E> comparator;

Source code here (line 108)

Why the need for using a type that is super of E and not simply E.

In other words, why not define the comparator just like below:

    private final Comparator<E> comparator;

What is the motivation behind that extra abstraction?

CodePudding user response:

Because why not.

Given a comparator that can compare any 2 CharSequence objects (CharSequence is an interface; String, StringBuilder, and a few other things implement it), then.. that is just as good when you have a need to compare only strings. All Strings are also CharSequences, so a comparator that can tell you for any 2 charsequence objects which one 'comes first' can do the job perfectly well.

Generics are invariant by default, so if you have a PriorityQueue<String>, and it worked like you want to, it'd look like Comparator<E>, which means Comparator<String>, and a Comparator<CharSequence> is not compatible with that. Like passing a String to a method that wants an Integer object, it just doesn't compile.

Hence, <? super E> so that you can pass a Comparator<CharSequence>.

It doesn't come up often, of course, but it's 'more correct' this way. I'm sure you'd be surprised if you so happen to have a comparator of CharSequences laying about and can't use it to power a PriorityQueue<String>.

  • Related