按属性对对象列表进行分组并计算每个键的对象属性的平均值

Rob*_*die 4 java java-8 java-stream

假设我有一个 Person 类:

class Person {
    String firstName;
    String age;

    public String getFirstName() {
        return firstName;
    }

    public String getAge() {
        return age;
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个List<Person>as 输入。作为输出,我想得到DoubleStream每个 的平均年龄firstName。我目前已经像这样实现了它,它的工作原理:

public DoubleStream getAverageAgesPerFirstName(List<Person> people) {
    return people
            .stream()
            .collect(
                    groupingBy(Person::getFirstName)
            )
            .entrySet()
            .stream()
            .collect(
                    toMap(Entry::getKey, this::getAverageAge)
            )
            .values()
            .stream()
            .mapToDouble(Double::doubleValue)
}

private double getAverageAge(Entry<String, List<Person>> entry) {
        return entry.getValue().stream().map(Person::getAge).mapToDouble(Integer::doubleValue).average().orElse(0);
    }
Run Code Online (Sandbox Code Playgroud)

我确实觉得应该有一种更有效的方法来解决这个问题。最值得注意的是,我在再次将它们转换为流之前创建了两个中间映射。

Ous*_* D. 5

使用下游收集器对分组应用进一步的操作,例如:

return people.stream()
             .collect(Collectors.collectingAndThen(
                 Collectors.groupingBy(Person::getFirstName, 
                    Collectors.averagingDouble(Person::getAge)), 
                        v -> v.values().stream().mapToDouble(Double::doubleValue));
Run Code Online (Sandbox Code Playgroud)