我有一个Event
s
public class Event {
Location location;
double turnout;
//... other fields & getters
}
统计课程EventStatistics
public class EventStatistics {
// Stats properties e.g. turnout standard deviation/median
public EventStatistics(List<Event> events) {
// Generate stats
}
}
我需要按位置对所有事件进行分组。创建位置和事件统计信息的地图Map<Location, EventStatistics>
小组是:
Map<Location, List<Event>> byLocation = events.stream().collect(groupingBy(Event::getLocation));
我知道有一个超载的groupingBy(function, collector)
收藏家。我可以用某种方式在单个流中生成Map<Location, EventStatistics>
吗?
答案 0 :(得分:8)
您所需要的只是collectingAndThen:
Map<Location, EventStatistics> result =
events.stream()
.collect(Collectors.groupingBy(Event::getLocation,
Collectors.collectingAndThen(
Collectors.toList(),
EventStatistics::new)));
答案 1 :(得分:1)
如果您的EventStatistics
能够接受单个Events
而不是完整列表,并且有合并两个统计信息的方法,例如
EventStatistics {
public EventStatistics() {}
public void addEvent(Event e);
public EventStatistics merge(EventStatistics toMerge);
}
groupingBy(Event::getLocation, Collector.of(EventStatistics::new, EventStatistics::accept, EventStatistics::merge));
此处,无参数构造函数为Supplier
,accept
为accumulator
,merge
为combiner
。
答案 2 :(得分:1)
您可以使用Collector
构建自己的Collector.of(...)
,如下所示:
Map<Location, EventStatistics> collect = events.stream().collect(groupingBy(Event::getLocation,
Collector.of(ArrayList::new,
List::add,
(left, right) -> { left.addAll(right); return left; },
EventStatistics::new)
));