Java 8查询-基于键和多个对象列表的分组计算

Java 8查询-基于键和多个对象列表的分组计算,java,java-8,Java,Java 8,我需要一些Java 8解决方案的帮助来计算总数。 假设我有3个item对象,每个对象都包含一个(2或3)个tax对象的列表。请在下面找到该物体的详细图像- 项目1 (列表) 税1-Id-1 |名称-A |描述|金额-Rs.5 |更多对象 税务2-Id-2 |姓名-B |描述|金额-10卢比|更多对象 税务3-Id-3 |姓名-C |描述|金额-Rs.8 |更多对象 项目2 (列表) 税1-Id-1 |名称-A |描述|金额-Rs.9 |更多对象 税务3-Id-3 |姓名-C |描述|金额-10

我需要一些Java 8解决方案的帮助来计算总数。
假设我有3个item对象,每个对象都包含一个(2或3)个tax对象的列表。请在下面找到该物体的详细图像-

项目1
(列表)
税1-Id-1 |名称-A |描述|金额-Rs.5 |更多对象
税务2-Id-2 |姓名-B |描述|金额-10卢比|更多对象
税务3-Id-3 |姓名-C |描述|金额-Rs.8 |更多对象

项目2
(列表)
税1-Id-1 |名称-A |描述|金额-Rs.9 |更多对象
税务3-Id-3 |姓名-C |描述|金额-10卢比|更多对象

现在,
我已经创建了一个新对象(聚合),该对象需要是基于Id的总数
例如:上述信息应包含3个合计对象,合计金额
税务-1 |名称-A |说明|金额-14卢比
税务-2 |名称-B |说明|金额-10卢比
税务-2 |名称-B |说明|金额-18卢比

我能够通过循环每个对象并将其添加到地图中来实现这一点。如果键存在,我将从对象聚合中取出amount值,并将amount添加到现有amount中。如果没有,我将创建一个新的聚合对象并将其添加到映射中,但我希望在Java 8中是否有一种更优化的方法来实现这一点

全局变量-
Map taxAggreg

for (Item item: Items) {
    List < Tax > taxes = item.getTaxes;
    for (Tax tax: taxes) {
        createTax(Tax tax);
    }
}

private void createTax(Tax tax) {
    if (!taxAggreg.isEmpty() && taxAggreg.containsKey(tax.getTaxId())) {
        Aggregate aggreg = taxAggreg.get(tax.getTaxId());
        aggreg.setTaxAmount(aggreg.getTaxAmount().add(tax.getTaxAmount()));
        taxAggreg.put(tax.getTaxId(), aggreg);
    } else {
        taxAggreg.put(tax.getTaxId(), new Aggregate(tax.getTaxId(), tax.getName(),
            tax.getTaxAmount()));
    }
}
用于(项目:项目){
列表Tax=item.getTaxes;
用于(税:税){
创设税(税);
}
}
个人所得税(税){
如果(!taxAggreg.isEmpty()&&taxAggreg.containsKey(tax.getTaxId())){
Aggregate aggreg=taxagreg.get(tax.getTaxId());
aggreg.setTaxAmount(aggreg.getTaxAmount().add(tax.getTaxAmount());
taxAggreg.put(tax.getTaxId(),aggreg);
}否则{
taxAggreg.put(tax.getTaxId()、新聚合(tax.getTaxId()、tax.getName()、新聚合),
tax.getTaxAmount());
}
}

也许类似的方法可以奏效:

    List<Aggregate> list1 = new ArrayList<Aggregate>();      
    List<Aggregate> list2 = new ArrayList<Aggregate>();    

    // Add your data to lists...

    // Now create maps with the identity for each object in lists
    Map<String, Aggregate> aggregateMap1 = list1.stream().collect(Collectors.toMap(Aggregate::getId, Function.identity()));
    Map<String, Aggregate> aggregateMap2 = list2.stream().collect(Collectors.toMap(Aggregate::geId, Function.identity()));

    // Now merge lists and add the amounts together
    List<Aggregate> result = aggregateMap1.keySet().forEach(key -> aggregateMap1.merge(key,
            aggregateMap2.get(key),
            (aggr1, aggr2) -> {
                aggr1.setAmount(aggr1.getAmount() + aggr2.getAmount());
                return aggr1;
            })).values().stream().collect(Collectors.toList());;
List list1=new ArrayList();
List list2=新的ArrayList();
//将您的数据添加到列表。。。
//现在为列表中的每个对象创建具有标识的贴图
Map aggregateMap1=list1.stream().collect(Collectors.toMap(Aggregate::getId,Function.identity());
Map aggregateMap2=list2.stream().collect(Collectors.toMap(Aggregate::geId,Function.identity());
//现在合并列表并将金额相加
列表结果=aggregateMap1.keySet().forEach(键->aggregateMap1.merge(键,
aggregateMap2.get(键),
(aggr1,aggr2)->{
aggr1.setAmount(aggr1.getAmount()+aggr2.getAmount());
返回aggr1;
})).values().stream().collect(Collectors.toList());;

没有测试。也可以进行微调。

首先,平整item的标记列表,然后将Tax对象转换为聚合对象。然后使用
收集器按税务id映射。toMap
然后合并具有相同id的税务对象

Map<Integer, Aggregate> resMap = items.stream()
                .flatMap(item -> item.getTaxes().stream())
                .map(tax -> new Aggregate(tax.getTaxId(), tax.getName(), tax.getTaxAmount()))
                .collect(Collectors.toMap(Tax::getTaxId, e -> e,    
                                  (a, b) -> new Aggregate(a.getTaxId(), a.getName(), 
                                                   a.getTaxAmount().add(b.getTaxAmount()))));

在问题中添加了逻辑。你试过这个吗?我刚上网。我将尝试提供的解决方案。谢谢你的意见。我过些时候再给你回复。你能解释一下你在toMap中做了什么吗?我问这个问题是因为你创建了一个新的聚合对象,而在中,我们只应该修改聚合对象中的现有值。@JustinPeter解释addedI刚刚上线。我将尝试提供的解决方案。谢谢你的意见。我过些时候再给你打电话。有问题问你。我们是否正在为每个项目集合创建一个列表?因为如果是这样的话。项目列表可能是动态的,这可能会导致不必要的内存使用。如果我没弄错的话,你把每一个聚合加起来就成了我们的第一张地图?是的。如果您想保持聚合的原样,您应该创建一个新对象,并以aggr=new Aggregate()的形式返回它;aggr.setAmount(aggr1.getAmount()+aggr2.getAmount());返回aggr;
Collectors.toMap(Tax::getTaxId, e -> e,    
                    (a, b) -> new Aggregate(a.getTaxId(), a.getName(),
                                            a.getTaxAmount().add(b.getTaxAmount())))