上一次我发现了Java8及更高版本的函数式编程的漏洞,我发现了Collectors类中的一个静态方法mapping。
我们有一个这样的班级员工:
@AllArgsConstructor
@Builder
@Getter
public class Employee {
private String name;
private Integer age;
private Double salary;
}假设我们有一个Employee类的POJO列表,并且我们想要接收所有雇员姓名的列表。我们有两种方法,比如:
List<Employee> employeeList
= Arrays.asList(new Employee("Tom Jones", 45, 15000.00),
new Employee("Harry Andrews", 45, 7000.00),
new Employee("Ethan Hardy", 65, 8000.00),
new Employee("Nancy Smith", 22, 10000.00),
new Employee("Deborah Sprightly", 29, 9000.00));
//IntelliJ suggest replacing the first approach with ```map``` and ```collect```
List<String> collect =
employeeList
.stream()
.collect(
Collectors.mapping(Employee::getName, Collectors.toList()));
List<String> collect1 =
employeeList
.stream()
.map(Employee::getName)
.collect(Collectors.toList());我知道第一种方法在Stream上使用终端操作,第二种方法在Stream上使用中间操作,但我想知道第一种方法的性能是否会比第二种方法差,反之亦然。如果您能解释第一种情况的潜在性能下降,当我们的数据源(employeeList)的大小将显着增加时,我将不胜感激。
编辑:
我创建了一个简单的两个测试用例,它们由一个简单的for循环中生成的记录提供。因此,对于小数据量输入,传统‘’方法与Stream.map使用率和Collectors.mapping之间的差异是边缘的。另一方面,在我们密集增加数据数量的场景中,比如30000000,令人惊讶的是,Collectors.mapping开始工作得更好一些。为了不让数据输入空手可得,30000000 Collectors.mapping与@RepeatedTest一样持续了10次56 seconds迭代,对于相同的迭代,使用相同的数据输入,更容易识别,比如Stream.map,然后是collect last 5 second longer。我知道我的临时测试并不是最好的,由于JVM优化,它不能说明现实,但我们可以断言,对于大量的数据输入,Collectors.mapping可能更可取。不管怎么说,我觉得这个
发布于 2019-10-15 15:25:30
我怀疑是否存在有意义的性能差异。你必须根据你的数据对其进行基准测试才能确定。
请注意,mapping实际上并不打算直接用作收集器,而是用作另一个收集器中的下游收集器:
mapping()收集器在多级缩减中使用时最有用,例如groupingBy或partitioningBy的下游。
在Edition第三版中也有一些关于这方面的内容(在项目46中,在214页下面大约2/3的地方,开始的段落是“由counting方法返回的收集器”)。基本上,它告诉我们不要在这里的第一种方式中使用像mapping这样的东西。
https://stackoverflow.com/questions/58389258
复制相似问题