sta*_*one 4 java java-8 java-stream
请考虑以下未编译的示例:
List<Integer> list = Arrays.asList(1, 2, -3, 8);
list.stream()
.filter(x -> x > 0)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)
.stream() // Stream<Object>
.map(x -> x * 2)
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
如果我更换
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)
Run Code Online (Sandbox Code Playgroud)
同
.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)
代码将被编译.那么问题是我如何collect()用供应商和累加器(我需要它)来编写能够在之后调用stream()它?
您似乎已经使用ArrayList构造函数创建了一个原始方法引用ArrayList::new.
类型参数未推断为:
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)
Run Code Online (Sandbox Code Playgroud)
期望3个参数的3参数重载collect,第一个是a Supplier<R>.在这一点上是没有关系的collect方法的类型参数R和T它是Integer在这里.推断这个的唯一方法是通过第二个参数,a BiConsumer<R, ? super T>.这里有ArrayList::add,这使编译器无法推断R.
您必须提供R第一个参数中的内容,即供应商.您可以向类提供显式类型参数以在方法引用上创建.
.collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll)
Run Code Online (Sandbox Code Playgroud)
这个编译,输出是预期的:
2
4
16
Run Code Online (Sandbox Code Playgroud)
使用时Collectors.toList(),您只提供一个参数.
public static <T> Collector<T,?,List<T>> toList()
这里只有一个类型参数T,因此编译器可以正确地推断出这T是Integer,因此List<Integer>创建了a ,允许代码进行编译.类型参数的Collector返回绑定T到List<T>,让编译器进行类型推断.
请注意,这只是首先需要,因为没有目标类型来帮助进行类型推断; 你继续使用流操作,并System.out.println在最后调用,这可能需要一个Object.
如果你有这个代码:
List<Integer> modified = list.stream()
.filter(x -> x > 0)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Run Code Online (Sandbox Code Playgroud)
然后,目标类型推断将为Integer类型参数提供ArrayList::new.这也编译.
| 归档时间: |
|
| 查看次数: |
73 次 |
| 最近记录: |