java - Stream 中 "filter then map"和 "map then filter"的性能是否不同?

标签 java java-8 java-stream

我想知道什么更快:按字段过滤自定义对象,然后按其字段映射,反之亦然(先映射,然后过滤)。
最后,我通常想将映射的字段收集到一些 Collection 中。

比如最简单的Person类:

public class Person {
    String uuid;
    String name;
    String secondName;
}

现在让我们有一个List<Person> persons .

List<String> filtered1 = persons
                .stream()
                .filter(p -> "NEED_TOY".equals(p.getName()))
                .map(Person::getName)
                .collect(Collectors.toList());
// or?
List<String> filtered2 = persons
                .stream()
                .map(Person::getName)
                .filter(p -> "NEED_TOY".equals(p))
                .collect(Collectors.toList());

最佳答案

在这个具体的例子中,调用 Person.getName() 基本上没有任何成本,这无关紧要,您应该使用您认为最易读的内容(并在可能之后进行过滤)甚至会稍微快一些,因为正如 TJ 所提到的,映射操作是过滤操作的一部分)。

但是,如果映射操作的成本很高,那么首先过滤(如果可能)会更有效,因为流不必映射已过滤掉的元素。

让我们举一个人为的例子:你有一个 ID 流,对于流中的每个偶数 ID,你必须执行一个 http GET 请求或一个数据库查询来获取这个 ID 标识的项目的详细信息(和从而将 ID 映射到详细对象)。

假设流是由一半奇数ID和一半偶数ID组成,并且每个请求花费相同的时间,你会先通过过滤将时间分成两半。如果每个 http 请求需要 1 秒,并且您有 60 个 ID,那么通过先过滤,同一任务的处理时间将从 60 秒减少到 30 秒,同时您还可以减少网络和外部 http API 的费用。

关于java - Stream 中 "filter then map"和 "map then filter"的性能是否不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57536144/

相关文章:

java - 带屏障的进程间同步

java - 如何将 IStatus 对象的 java 8 lambda 表达式传递给 Logger api(自定义记录器)

java - 检查自定义对象列表是否具有与 Java 8 中的属性相同的值

java - 使用 Java 中的可比较递归地将节点添加到 BST

java - 从 Java URL 中提取文件名(文件 : and http/https protocol)?

java - 我在哪里可以找到 Java 8 src.zip

Java:如何将类传递给 lambda

Java Stream 过滤器嵌套对象返回顶级字段

java - Lambda 表达式创建以整数为键、以列表为值的映射

java - 将整个相对布局变成一个按钮