Java 8 Streams - 收集与减少 [英] Java 8 Streams - collect vs reduce

查看:237
本文介绍了Java 8 Streams - 收集与减少的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您何时使用 collect() vs reduce()?有没有人有一个好的,具体的例子说明什么时候以某种方式更好?

When would you use collect() vs reduce()? Does anyone have good, concrete examples of when it's definitely better to go one way or the other?

Javadoc提到collect()是一个可变的减少

鉴于它是一个可变的减少,我认为它需要同步(内部),这反过来可能对性能有害。据推测, reduce()更容易并行化,代价是必须在reduce中的每个步骤之后创建一个新的数据结构。

Given that it's a mutable reduction, I assume it requires synchronization (internally) which, in turn, can be detrimental to performance. Presumably reduce() is more readily parallelizable at the cost of having to create a new data structure for return after every step in the reduce.

上面的陈述是猜测而且我喜欢这里的专家。

The above statements are guesswork however and I'd love an expert to chime in here.

推荐答案

首先,返回值不同:

<R,A> R collect(Collector<? super T,A,R> collector)

T reduce(T identity, BinaryOperator<T> accumulator)

所以收取返回任何 R reduce 返回 T - Stream 的类型。

So collect returns any R whereas reduce returns T - the type of the Stream.

reduce fold 操作,它将二元运算符应用于流中的每个元素,其中运算符的第一个参数是前一个应用程序的返回值,第二个参数是当前流元素。

reduce is a "fold" operation, it applies a binary operator to each element in the stream where the first argument to the operator is the return value of the previous application and the second argument is the current stream element.

集合是一个聚合操作,其中创建了一个集合并且每个元素都被添加到那个集合。然后将流的不同部分中的集合添加到一起。

collection is an aggregation operation where a "collection" is created and each element is "added" to that collection. Collections in different parts of the stream are then added together.

您链接的文档给出了两种不同方法的原因:

The document you linked gives the reason for having two different approaches:

如果我们想要获取字符串流并将它们连接成
单个长字符串,我们可以通过普通缩减来实现这一点:

If we wanted to take a stream of strings and concatenate them into a single long string, we could achieve this with ordinary reduction:

 String concatenated = strings.reduce("", String::concat)  

我们会得到理想的结果,它甚至可以并行工作。
但是,我们可能对性能不满意!这样的
实现会进行大量的字符串复制,而运行
的时间将是字符数的O(n ^ 2)。一个更高性能的
方法是将结果累积到StringBuilder中,
是一个用于累积字符串的可变容器。我们可以使用
相同的技术来并行化可变缩减,就像我们使用普通的
缩减一样。

We would get the desired result, and it would even work in parallel. However, we might not be happy about the performance! Such an implementation would do a great deal of string copying, and the run time would be O(n^2) in the number of characters. A more performant approach would be to accumulate the results into a StringBuilder, which is a mutable container for accumulating strings. We can use the same technique to parallelize mutable reduction as we do with ordinary reduction.

所以重点是两种情况下的并行化是相同的,但在 reduce 的情况下,我们将函数应用于流元素本身。在 collect 的情况下,我们将函数应用于可变容器。

So the point is that the parallelisation is the same in both cases but in the reduce case we apply the function to the stream elements themselves. In the collect case we apply the function to a mutable container.

这篇关于Java 8 Streams - 收集与减少的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆