为了账号安全,请及时绑定邮箱和手机立即绑定

如何根据特定字段从列表中删除重复的对象,但在删除之前添加数量?

如何根据特定字段从列表中删除重复的对象,但在删除之前添加数量?

回首忆惘然 2023-08-23 15:02:40
我有一个具有多个字段的程序集类。我需要根据程序集代码从程序集对象列表中删除程序集类的重复对象,但在删除之前,我需要将程序集数量添加到匹配的程序集对象的数量中。package com.company;import java.util.ArrayList;import java.util.HashSet;import java.util.List;public class Main {    public static void main(String[] args) {        List<Assembly> assemblies = new ArrayList<>();        assemblies.add(new Assembly("abc1", 3.0));        assemblies.add(new Assembly("abc2", 6.0));        assemblies.add(new Assembly("abc3", 8.4));        assemblies.add(new Assembly("abc4", 9.0));        assemblies.add(new Assembly("abc1", 4.2));        assemblies.add(new Assembly("abc1", 6.3));        System.out.println("List with duplicates: "+assemblies);        HashSet<String> assmCode=new HashSet<>();        assemblies.removeIf(e->!assmCode.add(e.getAssemblyCode())); //remove the last two abc1        //but i need to add 4.2, 6.3 to 3.0 before removing        System.out.println("List without duplicates: "+assemblies);    }}class Assembly{    private String assemblyCode;    private double assemblyQty;    //There will be more such fields    public Assembly(String assemblyCode, double assemblyQty) {        this.assemblyCode = assemblyCode;        this.assemblyQty = assemblyQty;    }    public String getAssemblyCode() {        return assemblyCode;    }请让我知道我是否可以在删除重复对象之前执行此类操作。我对 java 的集合 api 很陌生,很抱歉问这个问题解决方案是否简单。只是为了澄清一下,输出必须是这样的:包含重复项的列表: [Assembly{assembleCode='abc1', assemblyQty=3.0}, Assembly{ assemblyCode='abc2', assemblyQty=6.0}, Assembly{ assemblyCode='abc3', assemblyQty=8.4}, Assembly{ assemblyCode='abc4 ', assemblyQty=9.0}, Assembly{ assemblyCode='abc1', assemblyQty=4.2}, Assembly{ assemblyCode='abc1', assemblyQty=6.3}]没有重复项的列表:[Assembly{assembleCode='abc1', assemblyQty=13.5}, Assembly{ assemblyCode='abc2', assemblyQty=6.0}, Assembly{ assemblyCode='abc3', assemblyQty=8.4}, Assembly{ assemblyCode='abc4 ', 装配数量=9.0}]
查看完整描述

1 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

我需要根据程序集代码从程序集对象列表中删除程序集类的重复对象,但在删除之前,我需要将程序集数量添加到匹配的程序集对象的数量中。


您需要保留重复值才能重用它们。

removeIf()不会捕获此信息。


您可以使用迭代器删除元素并引入 Map 变量来存储重复信息:


Map<String, Double> assemblyDupMap = new HashMap<>();

for (Iterator<Assembly> it = assemblies.iterator(); it.hasNext(); ){

      Assembly a = it.next();

      if(!assmCode.add(a.getAssemblyCode())){ 

         // store the duplicate information 

         double currentQty = assemblyDupMap.getOrDefault(a.getAssemblyCode(), 0D);

         assemblyDupMap.put(a.getAssemblyCode(), currentQty + a.getAssemblyQty()); 

         // remove it from the list

         it.remove();        

      }


};

然后更新数量:


assemblies.forEach( a -> Optional.ofNullable(assemblyDupMap.get(a.getAssemblyCode()))

                                 .ifPresent(qty -> a.incrementQty(qty))

                  );

正如您所注意到的,它已经足够冗长了。本质上是因为我们需要更新列表的元素。

如果创建新列表而不是使用现有列表是可以接受的,那么流方法会更简洁。


按 Map 中的汇编代码对对象进行分组,按代码求和它们的数量,并仅保留对象作为结果:


new ArrayList<>(assemblies.stream()

                          .collect(toMap(Assembly::getAssemblyCode, o -> o,

                                         (a, b) -> new Assembly(a.getAssemblyCode(),

                                                                a.getAssemblyQty() + b

                                                                    .getAssemblyQty()),

                                         LinkedHashMap::new)

                          )

                          .values());

根据记录,对doubles 求和可能会产生“不良”结果。BigDecimal您可能感兴趣。


查看完整回答
反对 回复 2023-08-23
  • 1 回答
  • 0 关注
  • 101 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信