Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I was looking at the stream interface and found this method :

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

I can't find any reason why "? extends R" instead of R :

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

so what will be the difference if I make it like above ? isn't the "?" is the R variable that I pass ? and it will extend R I can't find a reason for it.

like image 984
Mohammad Karmi Avatar asked Dec 13 '18 06:12

Mohammad Karmi


2 Answers

It uses ? extends R to allow functions taken by map to be declared as returning a subtype of R

For example, given this stream:

Stream<Number> numberStream = Stream.of(1, 2L);

In the following map call, R is Number, but the function is of type Function<Number, Integer>:

Function<Number, Integer> function = n -> Integer.valueOf(n.intValue());
Stream<Number> numberStream2 = numberStream.map(function); //would have failed

If it did not take ? extends R, then function would have been an invalid argument (Function<Number, Number> would have been required)

like image 196
ernest_k Avatar answered Oct 02 '22 16:10

ernest_k


? extends R means you can pass an object whose class is derived by R, a.k.a subclass of R.

So the map function can produce R and R's subclass as result. That is reasonable.

For example, If we have these classes: Animal, Groose (extends Animal), Egg Function<Egg, Groose> hatching

You can write this code:

List<Egg> eggs = getEggs();
List<Animal> myPets = eggs.stream().map(hatching)....

You can see that your map function requires Animal type (R), but your mapper returns Groose type (which is ? extends R). If the map function writes as <R> Stream<R> map(Function<? super T, R> mapper);, you have to add another conversion from Groose to Animal.

You can refer to this answer and understand <? extends T>.

like image 41
Laohyx Avatar answered Oct 02 '22 15:10

Laohyx