在Brian Goetz的这个非常有趣但一岁的presentation中运行 - 在幻灯片链接中他提出了一个aggregateBy()
方法,据说在Stream API中,它应该聚合列表的元素(?)到地图(给定默认初始值和操纵值的方法(对于重复键也是如此) - 请参阅演示文稿中的下一张幻灯片。)
显然Stream API中没有这样的方法。还有另一种方法可以在Java 8中做类似的事情吗?
答案 0 :(得分:14)
可以使用Collectors
类完成聚合操作。所以在视频中,示例等同于:
Map<String, Integer> map =
documents.stream().collect(Collectors.groupingBy(Document::getAuthor, Collectors.summingInt(Document::getPageCount)));
groupingBy
方法会为您提供Map<String, List<Document>>
。现在,您必须使用下游收集器来汇总与每个密钥关联的List
中每个文档的所有页数。
这是通过向groupingBy
提供summingInt
的下游收集器来完成的,从而产生Map<String, Integer>
。
<小时/> 他们在文档中给出了基本相同的例子,他们计算了员工的总和。按部门划分的工资。
我认为他们删除了这个操作并创建了Collectors
类,而不是让一个有用的类包含很多通常会使用的减少。
答案 1 :(得分:3)
我们假设我们有一份员工名单及其部门和薪水,我们希望每个部门支付的总薪水。
有几种方法可以执行此操作,例如,您可以使用toMap
收集器来聚合每个部门的数据:
示例:
import static java.util.stream.Collectors.*;
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("John", "Sales", 10000),
new Person("Helena", "Sales", 10000),
new Person("Somebody", "Marketing", 15000));
Map<String, Double> salaryByDepartment = persons.stream()
.collect(toMap(Person::department, Person::salary, (s1, s2) -> s1 + s2));
System.out.println("salary by department = " + salaryByDepartment);
}
通常使用流,有几种方法可以获得所需的结果,例如:
import static java.util.stream.Collectors.*;
Map<String, Double> salaryByDepartment = persons.stream()
.collect(groupingBy(Person::department, summingDouble(Person::salary)));
供参考,Person类:
static class Person {
private final String name, department;
private final double salary;
public Person(String name, String department, double salary) {
this.name = name;
this.department = department;
this.salary = salary;
}
public String name() { return name; }
public String department() { return department; }
public double salary() { return salary; }
}
答案 2 :(得分:1)
This particular Javadoc entry是关于Java 8中这个聚合的最接近的东西。即使它是第三方API,签名看起来也很好 - 你提供了一些函数来从中获取值,一些终值函数的值(在这种情况下为零),以及一些函数将函数和值组合在一起。
感觉很像Collector,它可以让我们做到这一点。
Map<String, Integer> strIntMap =
intList.stream()
.collect(Collectors
.groupingBy(Document::getAuthor,
Collectors.summingInt(Document::getPageCount)));
然后我们的想法是,我们将列表中每个条目的作者姓名分组,并将作者的总页码加到Map<String, Integer>
中。