Java 将对象列表分组以创建扩展对象列表

Java 将对象列表分组以创建扩展对象列表,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我从数据库中获得了这些样本记录,这是分组查询的结果: [ { "name": "Troy", "acct": 1123, "type": " Savings", "total": 50 }, { "name": "Larry", "acct": 4233, "type": " Savings", "total": 200 }, { "name": "Troy", "acct": 1123, "type": " Curre

我从数据库中获得了这些样本记录,这是分组查询的结果:

[
 {
   "name": "Troy",
   "acct": 1123,
   "type": " Savings",
   "total": 50
 },
 {
   "name": "Larry",
   "acct": 4233,
   "type": " Savings",
   "total": 200
 },
 {
   "name": "Troy",
   "acct": 1123,
   "type": " Current",
   "total": 120
 },
 {
   "name": "Larry",
   "acct": 4233,
   "type": " Current",
   "total": 220
 }
]
现在,我需要创建一个如下所示的报告:

[
 {
   "name": "Troy",
   "acct": 1123,
   "totalSavings": 50,
   "totalCurrent": 120
 },
 {
   "name": "Larry",
   "acct": 4233,
   "totalSavings": 200,
   "totalCurrent": 220
 }
]

我已经尝试使用一些lambda技术,如下面的一种,但我仍然没有接近我想要的解决方案

 Map<String, List<DbTrans>> collect = transList.stream().collect(
          Collectors.groupingBy(f -> f.getType()));
Map collect=transList.stream().collect(
Collectors.groupby(f->f.getType());

首先,响应Dto与请求Dto不同,我建议创建一个新的响应类LETS调用它:

public class DbTransResponse {
    private String name;
    private String acct;
    private double totalSavings;
    private double totalCurrent;
    // getters and setters
}
那么结果可以是这样的:

List<DbTransResponse> result = transList.stream()
        .collect(Collectors.groupingBy(DbTrans::getAcct))
        .values().stream()
        .map(trans -> new DbTransResponse(
                trans.get(0).getName(),
                trans.get(0).getAcct(),
                trans.get(0).getTotal(),
                trans.get(1).getTotal()
        )).collect(Collectors.toList());

为此,您可以使用
collector::toMap
(通过单个
collect
操作)

还有一个用于
DbTransResponse
类的附加构造函数,不过您可以将此逻辑移动到方法中

DbTransResponse(DbTrans dbTrans) {
   this.name = dbTrans.getName();
   this.acct = dbTrans.getAcct();
   this.totalSavings = "Savings".equals(dbTrans.getType()) ? dbTrans.getTotal() : 0;
   this.totalCurrent = "Current".equals(dbTrans.getType()) ? dbTrans.getTotal() : 0;
}


可能是我在银行业工作:)但如果类型是交易类型,您的考虑是错误的,并且可能存在同一类型的多笔交易。但是奥兰托比应该回答这个问题。顺便说一句,按名称分组没有意义。帐户与个人唯一关联。因此,按accountnumber分组就足够了。除非我怀疑的不是帐户的所有者,而是交易发起人。@AlexandarPetrov我同意第二条评论,按帐户分组更好,关于第一条评论,如果OP想要用多个字段分组,那么执行
.collector(Collectors.groupingBy)并不容易(DbTrans::getName,Collectors.groupingBy(DbTrans::getAcct))).values().stream().flatMap(m->m.values().stream())
DbTransResponse{name='Larry', acct='4233', totalSavings=200.0, totalCurrent=220.0}
DbTransResponse{name='Troy', acct='1123', totalSavings=50.0, totalCurrent=120.0}
 Map<Integer, DbTransResponse> collect = transList.stream()
            .collect(Collectors.toMap(DbTrans::getAcct, 
                                      DbTransResponse::new, 
                                      DbTransResponse::merge));

 Collection<DbTransResponse> result = collect.values();
static DbTransResponse merge(DbTransResponse r1, DbTransResponse r2) {
        return new DbTransResponse(
                r1.name, r1.acct,
                r1.totalSavings + r2.totalSavings,
                r1.totalCurrent + r2.totalCurrent
        );
    }
DbTransResponse(DbTrans dbTrans) {
   this.name = dbTrans.getName();
   this.acct = dbTrans.getAcct();
   this.totalSavings = "Savings".equals(dbTrans.getType()) ? dbTrans.getTotal() : 0;
   this.totalCurrent = "Current".equals(dbTrans.getType()) ? dbTrans.getTotal() : 0;