我需要找到唯一的名称计数,以及列表中字段值的求和。
下面是我的POJO:
@Getter
@Setter
public class Orders {
private String dealId;
private String fieldId;
private String accountName;
private List<Demands> demands; //Demands contains multiple fields inside it, but I just need
//the 'amount' value mainly which is a BigDecimal.
}List of Orders(ordersList) :
DealId | FieldId | AccountName | Demand |
1 | 11 | ABC | 100,100 |
1 | 11 | ABC | 200 |
1 | 11 | PQR | 300,100 |
1 | 12 | ABC | 100 |
2 | 21 | ABC | 200 |
2 | 21 | PQR | 300,500 |
2 | 21 | XYZ | 100 |
2 | 22 | ABC | 200,100 |
2 | 22 | ABC | 300 |
End Result :
DealId | FieldId | AccountNameCount | DemandSum |
1 | 11 | 2 | 800 |
1 | 12 | 1 | 100 |
2 | 21 | 3 | 1100 |
2 | 22 | 1 | 600 | 我需要在一些POJO或集合中以这种格式获取最终结果,其中
AccountNameCount是一笔交易的特定FieldId的唯一帐户名的计数。DemandSum是特定FieldId在DealId下的需求值之和。
注意:需求是Orders模型中的一个列表,因此它可能有多个值,应该添加DealId下的特定FieldId的所有这些值。
例如, : for DealId 1,使用fieldid 11,有两个唯一的accountNames,并在该字段下添加所有需求值,dealId = 800
我正在使用Java 8流进行尝试,能够按dealId和fieldId对列表进行分组,但我不知道如何在fieldId级别上计算惟一的帐户名和需求值之和,而不影响性能。
Map<String, Map<String, List<Orders>>> map = ordersList.stream()
.collect(Collectors.groupingBy(Orders::getDealId, Collectors.groupingBy(Orders::getFieldId)));Collectors.reducing选项可用于在流中添加需求值,但由于需求是订单中的列表,因此此处不适用。
Collectors.reducing(BigDecimal.ZERO, Demands::getAmount, BigDecimal::add);任何帮助都是非常感谢的!
发布于 2021-10-03 19:54:26
可能是这样吧?
return orderList.stream()
.collect(Collectors.groupingBy(o -> Arrays.asList(o.dealId, o.fieldId)))
.entrySet().stream().map(e -> {
var stats = new OrderStats();
stats.dealId = e.getKey().get(0);
stats.fieldId = e.getKey().get(1);
stats.accountNameCount = e.getValue().stream()
.map(o -> o.accountName)
.distinct()
.count();
stats.demandSum = e.getValue().stream()
.flatMap(o -> o.demands.stream())
.map(d -> d.amount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
return stats;
})
.collect(Collectors.toList());我使用List作为密钥,以避免在分组Map中进行不必要的嵌套。这是因为List实现了基于内容的等式。
https://stackoverflow.com/questions/69427592
复制相似问题