Java 8 Stream API中的多个聚合函数 [英] Multiple aggregate functions in Java 8 Stream API
问题描述
我有一个类定义如
public class TimePeriodCalc {
private double occupancy;
private double efficiency;
private String atDate;
}
我想使用Java 8 Stream API执行以下SQL语句。
I would like to perform the following SQL statement using Java 8 Stream API.
SELECT atDate, AVG(occupancy), AVG(efficiency)
FROM TimePeriodCalc
GROUP BY atDate
我试过:
Collection<TimePeriodCalc> collector = result.stream().collect(groupingBy(p -> p.getAtDate(), ....
可以在代码中添加什么来选择多个属性?我正在考虑使用多个收集器,但实际上不知道如何这样做。
What can be put into the code to select multiple attributes ? I'm thinking of using multiple Collectors but really don't know how to do so.
推荐答案
要做到这一点没有自定义的收集器
(不再对结果进行流式传输),你可以这样做。它有点脏,因为它首先收集到 Map< String,List< TimePeriodCalc>>
然后流式传输该列表并获得平均加倍。
To do it without a custom Collector
(not streaming again on the result), you could do it like this. It's a bit dirty, since it is first collecting to Map<String, List<TimePeriodCalc>>
and then streaming that list and get the average double.
由于您需要两个平均值,它们会被收集到持有人
或对
,这种情况我正在使用 AbstractMap.SimpleEntry
Since you need two averages, they are collected to a Holder
or a Pair
, in this case I'm using AbstractMap.SimpleEntry
Map<String, SimpleEntry<Double, Double>> map = Stream.of(new TimePeriodCalc(12d, 10d, "A"), new TimePeriodCalc(2d, 16d, "A"))
.collect(Collectors.groupingBy(TimePeriodCalc::getAtDate,
Collectors.collectingAndThen(Collectors.toList(), list -> {
double occupancy = list.stream().collect(
Collectors.averagingDouble(TimePeriodCalc::getOccupancy));
double efficiency = list.stream().collect(
Collectors.averagingDouble(TimePeriodCalc::getEfficiency));
return new AbstractMap.SimpleEntry<>(occupancy, efficiency);
})));
System.out.println(map);
这篇关于Java 8 Stream API中的多个聚合函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!