Joh*_*0te 7 java reduce accumulate java-8 java-stream
我编写了这段代码,将一个单词列表缩减为多少单词以'A'开头.我只是为了学习Java 8而写它,所以我想更好地理解它[免责声明:我意识到这可能不是编写这段代码的最好方法; 这只是为了练习!].
Long countOfAWords = results.stream().reduce(
0L,
(a, b) -> b.charAt(0) == 'A' ? a + 1 : a,
Long::sum);
Run Code Online (Sandbox Code Playgroud)
中间参数/ lambda(称为累加器)似乎能够在没有最终'Combiner'参数的情况下减少完整列表.事实上,Javadoc实际上说:
{@code accumulator}函数充当融合映射器和累加器*,它有时比单独的映射和缩减更有效,*例如当知道先前减少的值允许您避免*某些计算时.
[编辑来自作者] -以下陈述是错误的,所以不要让它混淆你; 我只是把它放在这里,所以我不会破坏答案的原始背景.
无论如何,我可以推断累加器必须只输出组合器组合的1和0.我没有从文档中发现这一点特别明显.
我的问题
有没有办法在组合器执行之前查看输出是什么,所以我可以看到组合器组合的1和0的列表?这将有助于调试更复杂的情况,我相信我最终会遇到这种情况.
组合器不会减少0和1的列表.当流不是并行运行时,在这种情况下不使用,因此以下循环是等效的:
U result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
Run Code Online (Sandbox Code Playgroud)
并行运行流时,任务将跨越多个线程.因此,例如,管道中的数据被划分为块,其独立地评估和产生结果.然后使用组合器合并该结果.
因此,您将看不到减少的列表,而是2个值,即标识值或由求和的任务计算的另一个值.例如,如果在组合器中添加print语句
(i1, i2) -> {System.out.println("Merging: "+i1+"-"+i2); return i1+i2;});
Run Code Online (Sandbox Code Playgroud)
你可以看到这样的东西:
Merging: 0-0
Merging: 0-0
Merging: 1-0
Merging: 1-0
Merging: 1-1
Run Code Online (Sandbox Code Playgroud)
这将有助于调试更复杂的情况,我相信我会遇到事故.
更常见的是,如果您想在移动中查看管道上的数据,您可以使用peek(或者调试器也可以提供帮助).所以适用于你的例子:
long countOfAWords = result.stream().map(s -> s.charAt(0) == 'A' ? 1 : 0).peek(System.out::print).mapToLong(l -> l).sum();
Run Code Online (Sandbox Code Playgroud)
哪个可以输出:
100100
Run Code Online (Sandbox Code Playgroud)
[免责声明:我意识到这可能不是编写此代码的最佳方式; 这只是为了练习!].
实现任务的惯用方法filter是流,然后简单地使用count:
long countOfAWords = result.stream().filter(s -> s.charAt(0) == 'A').count();
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!:)
| 归档时间: |
|
| 查看次数: |
2542 次 |
| 最近记录: |