对于Java 8 POJO objects filter pojo based on common multiple key combination and sum on one field
中的示例总结之后,我需要创建一个Sales类型的新对象,其总和(group by的总和)如下所示
set logging on
b func2
commands
silent
bt 1
continue
end
b func1
commands
silent
bt 1
set logging off
continue
end
所以我在Sales中创建了相应的构造函数并尝试了
{
"month" : "Total",
"year": "2000",
"state" : "State1",
"city" : "City1",
"sales" : "15"
}
如何在Java 8中实现上述格式?
答案 0 :(得分:1)
您可以这样做:
您可以将groupingBy
收集器与合并功能一起使用,而不是第二toMap
。
list.stream()
.collect(Collectors.groupingBy(Sales::getState,
Collectors.toMap(Sales::getCity,Function.identity(),
(s1, s2) -> new Sales(s1.month,...,s1.getSales() + s2.getSales()))));
答案 1 :(得分:1)
您的方向正确。唯一需要做的是最后一步,即将所有销售编号组合到一个对象中。您不能仅使用summingInt
,因为它仅返回一个int,并且您没有其他字段来构造对象。您可以通过使用reduce
构造一个初始对象并添加字段值来实现此目的:
list.stream()
.collect(groupingBy(Sale::getState,
groupingBy(Sale::getCity,
reducing( (a, b) -> new Sale(a.getMonth(), a.getYear(), a.getState(), a.getCity(), a.getSale() + b.getSale()) ))));
如果您不在乎月份和年份,则还可以创建一个标识对象(初始对象),并仅向其中添加销售额。它可以减少创建的临时对象的数量:
list.stream()
.collect(groupingBy(Sale::getState,
groupingBy(Sale::getCity,
reducing(new Sale("Total", "2000", "", "", 0), (a, b) -> {
a.setState(b.getState());
a.setCity(b.getCity());
a.setSales(a.getSales() + b.getSales());
return a;
} ))));
确保所有对象的年份和月份都相同,否则将会丢失(除非您不在乎这种情况)。