I'm reading the java source code and I've found things as below:
http://www.java2s.com/Code/JavaAPI/java.util/newTreeSetEComparatorsuperEc.htm
I don't understand why the parameter of this constructor is <? super E>
.
As my understanding, it should be <? extend E>
instead of <? super E>
because if E is comparable, the children of E must be comparable whereas the parents of E may be not.
Let's consider three classes: Drink
, Juice extends Drink
, and OrangeJuice extends Juice
.
If I want a TreeSet<Juice>
, I need a comparator that will compare any two juices. Of course a Comparator<Juice>
will do this.
A Comparator<Drink>
will also do this, because it is able to compare any two drinks, and thus any two juices.
A Comparator<OrangeJuice>
will not do this. If I wanted to add an AppleJuice
to my set of juices, that is not compatible with this comparator as it can only compare orange juices.
You create a sorted set of bananas. To do that, you need to be able to compare the bananas. You can thus use a comparator of bananas to do that. But if you have a comparator that can sort any kind of fruit (including bananas), then that'll work too. So you can also use a Comparator<Fruit>
or even a Comparator<Food>
to sort your bananas.
That's why a Comparator<? super E>
is used.
If it was Comparator<? extends E>
, you would be able to create a set of bananas with a Comparator<DriedBanana>
. But that wouldn't work: a comparator of dried bananas can only compare dried bananas. Not all kinds of bananas.
For more information, also read What is PECS (Producer Extends Consumer Super)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With