我想知道什么更快:按字段过滤自定义对象,然后按其字段映射,反之亦然(先映射,然后过滤)。
最后,我通常想将映射的字段收集到一些 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/