Java 如何通过按结果分组创建新对象
例如 总结之后,我需要创建一个Sales类型的新对象,具有如下所示的总计(group by的sum result)Java 如何通过按结果分组创建新对象,java,java-8,grouping,Java,Java 8,Grouping,例如 总结之后,我需要创建一个Sales类型的新对象,具有如下所示的总计(group by的sum result) { "month" : "Total", "year": "2000", "state" : "State1", "city" : "City1", "sales" : "15" } 所以我在Sales中创建了相应的构造函数并尝试了 list.stream() .collect(groupingBy(Sale::getState,
{
"month" : "Total",
"year": "2000",
"state" : "State1",
"city" : "City1",
"sales" : "15"
}
所以我在Sales中创建了相应的构造函数并尝试了
list.stream()
.collect(groupingBy(Sale::getState,
groupingBy(Sale::getCity,
summingInt(Sale::getSales).Collectors.mapping(e -> new Sales ("Total","2000","State1","City1",<summingInt result should come here>),
Collectors.toList()))));
list.stream()
.collect(分组依据)(销售::getState,
groupingBy(销售::getCity,
summingit(Sale::getSales).Collectors.mapping(e->newsales(“总计”、“2000”、“状态1”、“城市1”),
收藏家;
如何在Java 8中实现上述格式?您可以这样做:
您可以使用带有合并功能的toMap
收集器,而不是第二个groupingBy
list.stream()
.collect(Collectors.groupingBy(Sales::getState,
Collectors.toMap(Sales::getCity,Function.identity(),
(s1, s2) -> new Sales(s1.month,...,s1.getSales() + s2.getSales()))));
您可以这样做:
您可以使用带有合并功能的toMap
收集器,而不是第二个groupingBy
list.stream()
.collect(Collectors.groupingBy(Sales::getState,
Collectors.toMap(Sales::getCity,Function.identity(),
(s1, s2) -> new Sales(s1.month,...,s1.getSales() + s2.getSales()))));
你的方向是正确的。唯一需要做的是最后一步,将所有销售编号合并到一个对象中。不能只使用
summingit
,因为它只返回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;
} ))));
确保所有对象的年和月都相同,否则它将丢失(除非您对此不在意)。您的方向是正确的。唯一需要做的是最后一步,将所有销售编号合并到一个对象中。不能只使用
summingit
,因为它只返回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;
} ))));
确保所有对象的年和月都相同,否则将丢失(除非您不在乎此情况)。要清楚,您需要按州和城市分组,然后将销售额设置为组内所有销售额的总和?是的,正确@texasbruce,因此对于州1,对于城市1,总计为15,使用这些值,我想创建一个单独的销售对象,对于其他州和城市,同样要清楚,你想按州和城市分组,然后将销售额设置为组内所有销售额的总和?是的,正确@texasbruce,因此对于州1,城市1,总计为15,使用这些值,我想创建一个单独的销售对象,对于其他州,同样,citiesOP想创建新对象。此代码将覆盖第一个对象的Sales@texasbruce,感谢您这么说。OP想创建新对象。此代码将覆盖第一个对象的Sales@texasbruce,谢谢你这么说。