Java8 stream.reduce()具有3个参数-获得透明度
我写这段代码是为了减少单词列表,以减少单词中以“ A”开头的单词的数量。我只是为了学习Java 8而编写它,所以我想更好地理解它。
[免责声明:我意识到这可能不是编写此代码的最佳方法;它可能是编写代码的最佳方法。 这只是为了练习!]。
Long countOfAWords = results.stream().reduce( 0L,
(a, b) -> b.charAt(0) == 'A' ? a + 1 : a,
Long::sum);
中间参数/ 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;
当您并行运行流时,任务将分为多个线程。因此,例如,管道中的数据被划分为多个块,这些块分别评估并产生结果。然后使用合并器合并此结果。
因此,您将不会看到一个减少的列表,而是2个值,它们是标识值或一个任务计算出的另一个值的总和。例如,如果您在合并器中添加打印语句
(i1, i2) -> {System.out.println("Merging: "+i1+"-"+i2); return i1+i2;});
您可能会看到以下内容:
Merging: 0-0Merging: 0-0
Merging: 1-0
Merging: 1-0
Merging: 1-1
这将有助于调试更复杂的情况,我相信我会最终遇到的。
更一般而言,如果您想随时随地查看管道上的数据,则可以使用peek
(或者调试器也可以提供帮助)。因此适用于您的示例:
long countOfAWords = result.stream().map(s -> s.charAt(0) == 'A' ? 1 : 0).peek(System.out::print).mapToLong(l -> l).sum();
可以输出:
100100
[免责声明:我意识到这可能不是编写此代码的最佳方法;这只是为了练习!]。
完成任务的惯用方式filter
是流式传输,然后简单地使用count
:
long countOfAWords = result.stream().filter(s -> s.charAt(0) == 'A').count();
希望能帮助到你!:)
以上是 Java8 stream.reduce()具有3个参数-获得透明度 的全部内容, 来源链接: utcz.com/qa/416735.html