在Java8中并行使用BigDecimal进行分组和求和
我有一个产品列表,其中有一个属性。该列表可以包含公共产品名称,而其他属性则不同。因此,我想使用分组和求和,按产品和在Java8中共享公共名称的产品数量的总和对列表进行分组
Example:
[
{
"name":"Product A",
"amount":"40.00",
"description":"Info1",
"number":"65"
},
{
"name":"Product A",
"amount":"50.00",
"description":"Info2",
"number":"67"
},
{
"name":"Product A",
"amount":"100.00",
"description":"Info3",
"number":"87"
},
{
"name":"Product B",
"amount":"45.00",
"description":"Info4",
"number":"86"
},
{
"name":"Product D",
"amount":"459.00",
"description":"Info5",
"number":"7"
},
{
"name":"Product B",
"amount":"50.00",
"description":"Info6",
"number":"8"
}
]
输出应与此类似:
{
"Product A = 190.00":[
{
"name":"Product A",
"amount":"40.00",
"description":"Info1",
"number":"65"
},
{
"name":"Product A",
"amount":"50.00",
"description":"Info2",
"number":"67"
},
{
"name":"Product A",
"amount":"100.00",
"description":"Info3",
"number":"87"
}
],
"Product B=95.00":[
{
"name":"Product B",
"amount":"45.00",
"description":"Info4",
"number":"86"
},
{
"name":"Product B",
"amount":"50.00",
"description":"Info6",
"number":"8"
}
],
"Product D = 459.00":[
{
"name":"Product D",
"amount":"459.00",
"description":"Info5",
"number":"7"
}
]
我已经创建了一个bean类ProductBean
,它包含所有字段(名称、数量、描述和编号)以及相同的getter和setter。
productBeans有所有产品的列表
Map<String, List<ProductBean>> groupByProduct =
productBeans.stream()
.collect(Collectors.groupingBy(item -> item.getName()))
Map<String, BigDecimal> result =
productBeans.stream()
.collect(Collectors.groupingBy(ProductBean::getName,
Collectors.mapping(ProductBean::getAmount,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
groupByProduct具有按名称分组的产品列表。 结果将产品图作为键,将该产品的总量作为值
但在这里,我试图将产品和总量映射到产品列表中。我试图结合上面的代码来获得预期的输出,但未能实现。通过在地图上迭代,也可以实现同样的效果
但是,在合并上述代码以获得产品名称和金额作为键、列表作为值的映射时,任何帮助都是有帮助的
# 1 楼答案
似乎您需要这样的东西
Map<String, BigDecimal, List<ProductBean>>
,其中字符串表示name
,BigDecimal
是所有产品数量的总和,List<ProductBean>
是该特定组中的产品列表这样的映射是不可能的,因此,您已经设法分两个步骤来完成它,这不是非常有效,而且它不会将相关数据保存在一起,而是将其分为两个映射
我的建议是创建这样一个包装器类:
它将封装一组给定的
ProductBean's
维护相关数据,以提高可维护性和可读性现在,您可以通过以下方式完成手头的任务:
这将按
ProductBean
名称分组,然后将每个组映射到一个ResultSet
实例,该实例将封装该名称、该特定组中的金额总和以及该组中的整个ProductBean's
通过为映射创建一个方法,可以进一步重构上述流查询:
因此,将流查询呈现为:
# 2 楼答案
嗯,你几乎明白了
Collectors.groupingBy
允许使用第二个参数,该参数是将为键生成值的收集器。您只需从第二行将收集器作为第二个参数传递:# 3 楼答案
除了我前面的答案,我建议创建一个包装器类。如果出于任何原因,不想单独创建一个自定义类来包装结果,那么另一个解决方案如下:
其中
Main
是包含mapToSimpleEntry
的类,并且mapToSimpleEntry
定义为:此解决方案的优点是: