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



假设我有一个 Person 类:

class Person {
String firstName;
String age;
public String getFirstName() {
return firstName;
}
public String getAge() {
return age;
}
}

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

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);
}

我确实觉得应该有一种更有效的方法来解决这个问题。最值得注意的是,我正在创建两个中间地图,然后再将它们转换为流。

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

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

下面是使用averagingDouble收集器的简化版本:

public DoubleStream getAverageAgesPerFirstName(List<Person> people) {
return people.stream()
.collect(Collectors.groupingBy(Person::getFirstName,
Collectors.averagingDouble(p -> Double.valueOf(p.getAge()))))
.values()
.stream()
.mapToDouble(d -> d);
}

最新更新