Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the constructor of TreeSet<E> accept the parameter super of E instead of extend of E

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.

like image 303
Yves Avatar asked Oct 22 '17 14:10

Yves


2 Answers

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.

like image 53
Joe C Avatar answered Oct 06 '22 08:10

Joe C


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)?

like image 29
JB Nizet Avatar answered Oct 06 '22 09:10

JB Nizet