【发布时间】:2019-11-27 08:24:28
【问题描述】:
我有课
public class SomeClass {
private String date;
private int players;
private int currency;
// getters setters omitted for brevity
}
我收集了这些物品。现在我想按日期对这些对象进行分组并对玩家计数进行汇总并将currencyId 设置为0。我这样做是这样的:
list = list.stream()
.collect(
groupingBy(SomeClass::getDate,
collectingAndThen(reducing((a, b) -> {
a.setDate(a.getDate());
a.setPlayers(a.getPlayers() + b.getPlayers());
a.setCurrency(0);
return a;
}), Optional::get)))
.values();
一切都很好,除非我只有一个特定日期的对象。该对象没有将货币设置为 0(因为如果对象只有一个,则减少不起作用。)所以这是我的问题。
如果我有:
Object1 ("11.09", 12, 12)
Object2 ("11.09", 8, 13)
Object3 ("12.09", 1, 2)
Object4 ("12.09", 0, 1)
Object5 ("13.09", 12, 12)
输出必须是:
Object6 ("11.09", 20, 0)
Object7 ("12.09", 1, 0)
Object8 ("13.09", 12, **0**)
但是:
Object6 ("11.09", 20, 0)
Object7 ("12.09", 1, 0)
Object8 ("13.09", 12, **12**)
请帮忙
【问题讨论】:
-
你真的关心那个字段值吗?你需要对象实例吗?你不想得到一个
Map<String, Integer>每天的玩家人数吗? -
a.setDate(a.getDate())幸好没有操作。如果您实际上更改了 reducer 内部的分组键,那可能会破坏您的地图。 -
Reduction 不是用于操作源对象的工具。除此之外,收集器模式
groupingBy(f1, collectingAndThen(reducing(f2), Optional::get)可以简化为toMap(f1, Function.identity(), f2)。 -
@AntonKolosok 你的意思是,除了是一半的代码并且不需要运行结果映射来调用每个组上的
Optional::get吗? -
没有其他区别。两个收集器都会生成一张地图,而且通常两者都可用于生成相同的结果,但根据用例,一个可能比另一个更适合。另见this Q&A
标签: java java-8 stream java-stream