<r> Stream <r>映射(函数<!-?超级T,?扩展R->映射器)Stream

时间:2018-12-13 06:11:03

标签: java java-stream

我正在查看流接口,发现了这种方法:

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

我找不到“?扩展R”而不是R的任何原因:

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

那么,如果我像上面那样做,会有什么区别?是不是?我传递的R变量是多少?它将扩展R我找不到原因。

3 个答案:

答案 0 :(得分:7)

它使用? extends R来允许将map所采用的函数声明为返回R的子类型

例如,给定此流:

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

在随后的map调用中,RNumber,但是函数的类型为Function<Number, Integer>

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

如果不使用? extends R,则function将是无效的参数(将需要Function<Number, Number>

答案 1 :(得分:0)

? extends R意味着您可以传递其类是由R的子类R派生的对象。

因此map函数可以生成RR's subclass作为结果。那是合理的。

例如,如果我们有以下类: AnimalGroose (extends Animal)Egg Function<Egg, Groose> hatching

您可以编写以下代码:

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

您可以看到您的map函数要求使用Animal类型(R),但是您的映射器返回Groose类型(即? extends R)。如果map函数写为<R> Stream<R> map(Function<? super T, R> mapper);,则必须添加从GrooseAnimal的另一次转换。

您可以参考this answer并了解<? extends T>

答案 2 :(得分:0)

在Java中,泛型是不变的,这意味着即使S扩展了P,以下代码也会引发编译错误-

List<S> list1 = neww ArrayList<>();
List<P> list2 = list1 ; // compile error

但是如果您有Listthen,则可以执行以下操作:

List<S> list1 = neww ArrayList<>();
List<? extends P> list2 = list1 ;