【发布时间】:2020-02-11 19:33:44
【问题描述】:
上次我发现 Java 8 及更高版本的函数式编程的角落时,我在 Collectors 类中发现了一个静态方法 mapping。
我们有一个 Employee 类,例如:
@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 持续56 seconds 作为@RepeatedTest 进行10 次迭代,并且对于相同的迭代使用相同的数据输入更容易识别的方法,例如Stream.map 然后collect最后5 second longer。我知道我的临时测试不是最好的,并且由于 JVM 优化它无法说明现实,但我们可以声称对于大量数据输入Collectors.mapping 可能更可取。反正我觉得这个
【问题讨论】:
-
看看this post,这是一个类似的问题。种类繁多,经验数据和指向更多同类帖子的链接。对于由此产生的基线论点,存在差异,但它们并不重要。
-
@Naman 我看过这篇文章,但这个问题回答了一个问题,为什么我们需要
mapping和类似的方法来简化我们流上的收集操作。 -
我将引用安迪的回答 我怀疑是否存在有意义的性能差异。 您必须根据自己的数据对其进行基准测试才能确定。
标签: java functional-programming java-stream collectors