Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 703
Manikandan Kbk DIP Avatar asked Jun 09 '19 09:06

Manikandan Kbk DIP


People also ask

What is the purpose of map method of Stream in Java?

map. Returns a stream consisting of the results of applying the given function to the elements of this stream. This is an intermediate operation.

What is the use of Stream map() in Java 8?

Java 8 Stream's map method is intermediate operation and consumes single element forom input Stream and produces single element to output Stream. It simply used to convert Stream of one type to another.

How map function works in Java 8?

map(Function mapper) takes a function as an argument. For example, by using the map() function, you can convert a list of String into a List of Integer by applying the Integer. valueOf() method to each String on the input list. All you need is a mapping function to convert one object to the other.


1 Answers

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>.

like image 123
Oleksandr Pyrohov Avatar answered Sep 29 '22 08:09

Oleksandr Pyrohov