use*_*486 2 java reduce lambda java-8 java-stream
Stream Guru的问题非常简单:
我有这个:
List<MyBean> beans = new ArrayList<>();
beans.add(new MyBean("tutu"));
beans.add(new MyBean("toto"));
beans.add(new MyBean("titi"));
Run Code Online (Sandbox Code Playgroud)
比较:
StringBuilder reduced
= beans.parallelStream()
.map(MyBean::getName)
.reduce(new StringBuilder(), (builder, name) -> {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(name);
return builder;
}, (left, right) -> left.append(right));
Run Code Online (Sandbox Code Playgroud)
和
StringBuilder reduced
= beans.parallelStream()
.map(MyBean::getName)
.reduce(new StringBuilder(), (builder, name) -> {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(name);
return builder;
}/* WITHOUT THIRD PARAM*/);
Run Code Online (Sandbox Code Playgroud)
为什么,第二个解决方案没有编译...第三个参数是针对并行流...
你能解释为什么我无法编译第二个代码部分吗?
这种行为是因为这个重载减少了:
reduce(T identity, BinaryOperator<T> accumulator)
Run Code Online (Sandbox Code Playgroud)
取两个参数,第二个是a BinaryOperator<T>
,它基本上表示对两个相同类型的操作数的操作,产生与操作数相同类型的结果.在您的第二个代码片段中未遵循此合同,因为您的map
操作返回a Stream<String>
而标识属于类型StringBuilder
.为了防止编译器错误,只需使标识值以及累加器函数的操作数都是相同的类型,即:
StringBuilder reduced
= beans.stream()
.map(b -> new StringBuilder(b.getName()))
.reduce(new StringBuilder(), (builder, name) -> {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(name);
return builder;
}/* WITHOUT THIRD PARAM*/);
Run Code Online (Sandbox Code Playgroud)
另一方面这种超载reduce
:
reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
Run Code Online (Sandbox Code Playgroud)
接受一个BiFunction
可以消耗两种不同类型对象的第二个参数,这就是为什么你的第一个代码片段在没有编译器错误的情况下工作的原因.
最后,不要忘记更改上面的解决方案中显示的beans.parallelStream()
to beans.stream()
.
顺便说一句,请注意,在并行执行操作时,所述蓄能器,以及所述组合器,必须是缔合,无干扰和无状态.如果不考虑这一点,您的结果将是不确定的任意结果.
编辑:
正如霍尔格所说:
在定义中修改递减函数中的传入参数,即使它恰好在顺序上下文中产生预期结果.它还违反了第一个参数的合同,因为修改后的参数
StringBuilder
不再是标识值.你可以使用Reducing with immutable values,.map(MyBean::getName).reduce((a,b) -> a + ", " + b).orElse("");
或者使用Mutable Reduction.map(MyBean::getName).collect(Collectors.joining(", "));
归档时间: |
|
查看次数: |
420 次 |
最近记录: |