2

While going through the JAVA doc, I found following signature of comparing method

 static <T,U extends Comparable<? super U>>
Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

I understand that U should be comparable but what is the signification of using

Comparable<? super U>

instead of using just Comparable<U>

Similarly, What is the significance of using Function<? super T,? extends U> keyExtractor
over Function<T,U> keyExtractor

Tarun
  • 3,162
  • 3
  • 29
  • 45
  • 1
    Possible duplicate of [What is PECS (Producer Extends Consumer Super)?](https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super) – Ousmane D. Mar 24 '18 at 17:19
  • 1
    @Aominè I disagree. That question is about how to differentiate when to use which, among `extends` and `super`, whereas this question is about the "why". – Sweeper Mar 24 '18 at 18:45
  • @Sweeper but then your answer starts and ends with PECS... – Eugene Mar 24 '18 at 19:12

2 Answers2

2

Usually it means that a super class might implement Comparator. Like for example if Number implements Comparable, the a List<Integer>.sort(null) is OK, because the comparable is on a super class of Integer.

With out that, the comparator would required to be Comparable<Integer> and since the comparable is actually Comparable<Number> it wouldn't work.

markspace
  • 10,621
  • 3
  • 25
  • 39
2

The is using the principle of Producer Extends Consumer Super (PECS).

Basically, PECS says that if a generic parameter is used as a parameter type of a method, it should use contravariance i.e. super. If it is used as a return value type, it should use covariance i.e. extends.

U is constrained to extend Comparable<? super U>. Here, super is used to achieve contravariance for U. So even if U is String, you can pass in a Comparable<Object>.

The Function parameter type is Function<? super T,? extends U> to achieve contravariance on T (consumer, as is used in parameter type of Function) and covariance on U (as is used in return value type of Function). This enables you to pass a Function<Object, String> even if T is String and U is Object.

The significance is that without extends or super, this is called invariance. This means that you have to pass instances of exactly the generic parameter types T and U, which reduces flexibility.

To learn more about PECS, visit here.

Sweeper
  • 213,210
  • 22
  • 193
  • 313