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

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

问题描述

你什么时候会使用 collect()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 提到收集() 是一个可变的归约.

鉴于这是一个可变的减少,我认为它需要(内部)同步,而这反过来又会损害性能.据推测,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.

推荐答案

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.

collect 是一个聚合操作,其中创建了一个集合",并将每个元素添加"到该集合中.然后将流不同部分的集合相加.

collect 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:

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

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天全站免登陆