16

While reading the Stream interface source code I found this method signature:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

I wonder why the input type of mapper is ? super T while the output type is ? extends R, why not use ? extends for both?

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
toandv
  • 982
  • 13
  • 25
  • 2
    the difference between super and extends has been answered here: http://stackoverflow.com/questions/1368166/what-is-a-difference-between-super-e-and-extends-e – gapvision Aug 21 '15 at 11:41
  • I know the difference, but I wonder why they did that? – toandv Aug 21 '15 at 11:42
  • If you don't mind the different notation, here is an actual talk that explains it https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote-Duality – Benjamin Gruenbaum Aug 21 '15 at 15:53

3 Answers3

20

Consider you want to map a CharSequence to another CharSequence (thus T = R = CharSequence). Which functions will work for you?

Function<Object, String> fn1 = Object::toString;

Is it good for you? Yes, because it can take any CharSequence (which is also Object) and convert it to the String (which is also CharSequence).

Function<CharSequence, StringBuilder> fn2 = StringBuilder::new;

Is it good for you? Yes, because it can take any CharSequence and convert it to the StringBuilder (which is also CharSequence).

Function<String, String> fn3 = String::trim;

Is it good for you? No, because it cannot take any CharSequence, only some of them.

Thus you can see that first type argument must be CharSequence or any superclass, but second must be CharSequence or any subclass.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
13

Because of PECS :) - Producer Extends, Consumer Super

Producer Extends - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T

Consumer Super - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T

Community
  • 1
  • 1
Casper
  • 216
  • 2
  • 7
  • 4
    This answer, while saying correct facts, doesn't directly answer the question. Maybe add a sentence or two to tell how it relates to the Stream method mentioned above? – Paŭlo Ebermann Aug 21 '15 at 18:16
11

There is a rule of thumb which was first mentionned by Joshua Bloch in his Effective Java book which stands as PECS.

  • PE Producer extends
  • CS Consumer super

This function produce a result (? extends R) from what it received (? super T).

The documentation of java.util.Function is kinda clear on that :

Represents a function that accepts one argument and produces a result.

Community
  • 1
  • 1
Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76