为什么 Java Stream.map 采用 Function<?超级 P_OUT, ? 扩展 R> 映射器作为输入而不是 Function<P_OUT, ? 扩展 R>?

Man*_*DIP 5 java generics wildcard java-8 java-stream

为什么map将其输入作为 aFunction类型<? super P_OUT, ? extends R>而不是<P_OUT, ? extends R>

例如,当我这样做时,

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"?
Run Code Online (Sandbox Code Playgroud)

是不是因为没有限制方法引用?这是唯一的用例吗?

Ole*_*hov 6

通配符<? super T>允许您使用更广泛的类型集。

假设您有一些通用函数:

Function<Number, String> func = String::valueOf;
Run Code Online (Sandbox Code Playgroud)

那么你可以执行以下操作:

List<Integer> list = List.of(1, 2);
Stream<String> stream = list.stream().map(func);
Run Code Online (Sandbox Code Playgroud)

或以下内容:

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

这是可能的,因为 的参数Stream.map(...)是:

Function<? super T, ? extends R> mapper;
Run Code Online (Sandbox Code Playgroud)

这意味着,例如,如果T是类型Long1<? super Long>则将允许函数接受类型元素Long,并且以下赋值也将变为有效:

Function<? super Long, ? extends String> mapper = func;
Run Code Online (Sandbox Code Playgroud)

Function<T, ? extends R>上面的两个例子甚至都无法编译。


1 - 我们Stream<Long>从 的元素构造List<Long>