本文介绍了带有3个参数的Java8 stream.reduce() - 获得透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了这段代码,将一个单词列表缩减为多少单词以'A'开头。我只是写它来学习Java 8,所以我想更好地理解它 [免责声明:我意识到这可能不是编写这段代码的最好方法;这只是为了练习!]

I wrote this code to reduce a list of words to a long count of how many words start with an 'A'. I'm just writing it to learn Java 8, so I'd like to understand it a little better [Disclaimer: I realize this is probably not the best way to write this code; it's just for practice!].

Long countOfAWords = results.stream().reduce(
    0L,
    (a, b) -> b.charAt(0) == 'A' ? a + 1 : a,
    Long::sum);

中间参数/ lambda(称为累加器)似乎能够减少完整列表而不用最后的'Combiner'参数。事实上,Javadoc实际上说:

The middle parameter/lambda (called the accumulator) would seem to be capable of reducing the full list without the final 'Combiner' parameter. In fact, the Javadoc actually says:

- 以下陈述是错误的,所以不要让它混淆你;我只是把它放在这里,所以我不会破坏答案的原始背景。

- The following statement is wrong, so don't let it confuse you; I'm just keeping it here so I don't ruin the original context of the answers.

无论如何,我可以推断累加器必须只输出1和0组合器结合了。我没有从文档中发现这一点特别明显。

Anyway, I can infer that the accumulator must just be outputting 1's and 0's which the combiner combines. I didn't find this particularly obvious from the documentation though.

我的问题

有没有办法在组合器执行之前看到输出是什么,所以我可以看到组合器组合的1和0的列表?这将有助于调试更复杂的情况,我相信我最终会遇到这种情况。

Is there a way to see what the output would be before the combiner executes so I can see the list of 1's and 0's that the combiner combines? This would be helpful in debugging more complex situations which I'm sure I'll come across eventually.

推荐答案

组合器没有减少0和1的列表。当流不是并行运行时,在这种情况下不使用它,因此以下循环是等效的:

The combiner does not reduce a list of 0's and 1's. When the stream is not run in parallel it's not used in this case so that the following loop is equivalent:

U result = identity;
for (T element : this stream)
    result = accumulator.apply(result, element)
return result;

当您并行运行流时,任务将跨越多个线程。因此,例如,管道中的数据被划分为块,其独立地评估和产生结果。然后组合器用于合并该结果。

When you run the stream in parallel, the task is spanned into multiple threads. So for example the data in the pipeline is partitioned into chunks that evaluate and produce a result independently. Then the combiner is used to merge this results.

因此,您不会看到减少的列表,而是2个值,即身份值或由任务计算的另一个值求和。例如,如果在合并器中添加打印语句

So you won't see a list that is reduced, but rather 2 values either the identity value or with another value computed by a task that are summed. For example if you add a print statement in the combiner

(i1, i2) -> {System.out.println("Merging: "+i1+"-"+i2); return i1+i2;}); 

你可以看到这样的东西:

you could see something like this:

Merging: 0-0
Merging: 0-0
Merging: 1-0
Merging: 1-0
Merging: 1-1



更一般地说,如果你想在途中看到管道上的数据你可以使用 peek (或者调试器也可以帮助)。因此适用于您的示例:

More generally if you want to see the data on the pipeline on the go you can use peek (or the debugger could also help). So applied to your example:

long countOfAWords = result.stream().map(s -> s.charAt(0) == 'A' ? 1 : 0).peek(System.out::print).mapToLong(l -> l).sum();

可以输出:

100100



实现任务的惯用方法是过滤器流然后只需使用 count

The idiomatic way to achieve your task would be to filter the stream and then simply use count:

long countOfAWords = result.stream().filter(s -> s.charAt(0) == 'A').count();

希望有所帮助! :)

这篇关于带有3个参数的Java8 stream.reduce() - 获得透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 01:21