我收集了一些 Map<Pair<DateTime, String>, List<Entity>>
以前使用流对其进行分组。 Entity
是一个简单的类 int
财产和 getValue()
方法。
现在,我想把 Entity
使用我的简单 EntityAccumulator
将上一个Map的类型修改为 Map<Pair<DateTime, String>, EntityAccumulator>
. 就我所知,实现这一目标的唯一方法是创建自己的定制收集器,尽管我一直在努力 finisher()
应该返回的方法 Pair
.
或者,有没有更简单的方法来达到我想要的结果?
流处理
Map<Pair<DateTime, String>, EntityAccumulator> collect = entities.stream()
.collect(Collectors.groupingBy(entity-> Pair.of(entity.getTimestamp(), entity.getName())))
.entrySet().stream()
.collect(new EntityCollector()));
实体累加器
private static class EntityAccumulator {
private int result = 0.0;
public EntityAccumulator() { }
public EntityAccumulator(int result) {
this.result = result;
}
public void calculate(Entity entity) {
result += entity.getValue();
}
public EntityAccumulatoradd(EntityAccumulator other) {
return new EntityAccumulator(this.result + other.result);
}
}
收藏家
public class EntityCollector implements Collector<Map.Entry<Pair<DateTime, String>, List<Entity>>, EntityAccumulator, Map.Entry<Pair<DateTime, String>, EntityAccumulator>> {
@Override
public Supplier<EntityAccumulator> supplier() {
return EntityAccumulator::new;
}
@Override
public BiConsumer<EntityAccumulator, Map.Entry<Pair<DateTime, String>, List<Entity>>> accumulator() {
return (result, pairListEntry) -> pairListEntry.getValue().forEach(result::calculate);
}
@Override
public BinaryOperator<EntityAccumulator> combiner() {
return EntityAccumulator::add;
}
@Override
public Function<EntityAccumulator, Map.Entry<Pair<DateTime, String>, EntityAccumulator>> finisher() {
return (k) -> {
return null; // ??? HELP HERE
}
}
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.UNORDERED);
}
}
1条答案
按热度按时间mfuanj7w1#
显然,你真的想
或
取决于实际值类型。你的宣言
int result = 0.0
不太清楚。首先,如果要对组执行缩减,应该提供
Collector
将值作为groupingBy
收藏家。那么,这两个问题都不必解决,Map
也不是Map.Entry
.因为它基本上是将实体折叠为一个数字(对于每个组),所以可以使用现有的收集器,即。
summingInt
或者summingDouble
.创建自己的收集器时,不能在收集器函数中删除的finisher函数中重新生成信息。如果您的容器类型
EntityAccumulator
只包含一个数字,无法生成Map.Entry<Pair<DateTime, String>, EntityAccumulator>
从它那里。顺便说一下,您很少需要实现
Collector
与类的接口,即使在创建自定义收集器时也是如此。你可以简单地使用Collector.of
,指定函数和特性,以创建Collector
.所以用你原来的
EntityAccumulator
类别(假设,result
应该是int
以及0.0
你可以用达到上述目的。也可以分两步执行操作,就像您尝试使用
当然,这只是为了完整。这个答案开头显示的解决方案更简单、更有效。