Why does Java Stream.map take a Function<? super P_OUT, ? extends R> mapper as input instead of Function<P_OUT, ? extends R>?

Manikandan Kbk DIP :

Why does map take its input as a Function of type <? super P_OUT, ? extends R> instead of <P_OUT, ? extends R>?

When I do for example,

List<Integer> list = new ArrayList<>();
list.stream().map(xyz -> {}); // Here xyz is always of type Integer for this instance. 
                              // Then why does it take input as "? super Integer"?

Is it because of not restricting method references? Is that the only use case?

Oleksandr Pyrohov :

The wildcard <? super T> allows you to work with a broader set of types.

Suppose you have some generic function:

Function<Number, String> func = String::valueOf;

Then you could do the following:

List<Integer> list = List.of(1, 2);
Stream<String> stream = list.stream().map(func);

or the following:

List<Long> list = List.of(1L, 2L);
Stream<String> stream = list.stream().map(func);

And this is possible because the parameter to the Stream.map(...) is:

Function<? super T, ? extends R> mapper;

Which means that if, for example, T is of type Long1, then <? super Long> will allow the function to accept elements of type Long, and the following assignment will also become valid:

Function<? super Long, ? extends String> mapper = func;

With the Function<T, ? extends R> both examples above wouldn't even compile.


1 - We construct the Stream<Long> from the elements of the List<Long>.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=78470&siteId=1