以下是一个示例场景:
想象一下,我们有员工记录,如:
name, age, salary (in 1000 dollars)
a, 20, 50
b, 22, 53
c, 34, 79
等等。目标是计算不同年龄组的平均工资(例如21至30岁和31至40岁等)。
我想使用stream
执行此操作,我无法理解我需要使用groupingBy
来完成此操作。我想也许我需要定义某种元组年龄范围。有什么想法吗?
答案 0 :(得分:6)
以下代码应该可以满足您的需求。关键是"收藏家"支持分组的类。
Map<Double,Integer> ageGroup= employees.stream().collect(Collectors.groupingBy(e->Math.ceil(e.age/10.0),Collectors.summingInt(e->e.salary)));
图示假设薪水为整数但很容易切换为双倍
完整的程序看起来像
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("a",20,100));
employees.add(new Employee("a",21,100));
employees.add(new Employee("a",35,100));
employees.add(new Employee("a",32,100));
Map<Double,Integer> ageGroup= employees.stream().collect(Collectors.groupingBy(e->Math.ceil(e.age/10.0),Collectors.summingInt(e->e.salary)));
System.out.println(ageGroup);
}
public static class Employee {
public Employee(String name, int age, int salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
}
public String name;
public int age;
public int salary;
}
输出
{4.0=200, 2.0=100, 3.0=100}
答案 1 :(得分:2)
是的,您可以定义一个AgeGroup
界面,甚至是enum
这样的界面(假设Employee
定义):
enum AgeGroup {
TWENTIES,
THIRTIES,
FORTIES,
FIFTIES;
.....
}
Function<Employee, AgeGroup> employee2Group = e -> {
if(e.age >= 20 && e.getAge() < 30)
return AgeGroup.TWENTIES;
....
return null;
};
Map<AgeGroup, Double> avgByAgeGroup = employees.stream()
.collect(Collectors.groupingBy(employee2Group, Collectors.averagingInt(Employee::getSalary)));
avgByAgeGroup.get(AgeGroup.TWENTIES)