Java列表中重复元素的数值累加实现问题
按Type分组累加Amount和Quantity的实现问题
原始数据
原始列表元素包含Type(String)、Amount(Double)、Quantity(Integer)字段,示例如下:
Type: Type A, Amount : 55.0, Quantity : 0 Type: Type A, Amount : 55.0, Quantity : 5 Type: Type A, Amount : 44.35, Quantity : 6 Type: Type A, Amount : 55.0, Quantity : 0 Type: Type B, Amount : 7.0, Quantity : 1 Type: Type B, Amount : 7.0, Quantity : 1 Type: Type C, Amount : 1613.57, Quantity : 0 Type: Type C, Amount : 1613.57, Quantity : 1
需求
遍历列表,按Type分组,累加同组的Amount和Quantity,预期结果:
Type: Type A, Amount : 209.35, Quantity : 11 Type: Type B, Amount : 14.0, Quantity : 2 Type: Type C, Amount : 3227.14, Quantity : 1
尝试的代码(未成功)
List<Type> newList = new ArrayList(); for(int k = 0; k < typeList.size(); k++) { Type type= new Type(); Double totalAmount = Double.parseDouble("0"); type.setTypeName(typeList.get(k).getTypeName()); type.setAmount(chargeTypeList.get(k).getAmount()); newList.add(k, type); if(typeList.get(k).getChargeTypeName().equalsIgnoreCase(newList.get(k).getiTypeName())) { totalAmount += typeList.get(k).getAmount(); } }
要求:不通过硬编码判断重复的Type。
解决方案
方法一:使用HashMap分组累加
核心思路是用HashMap的键存储Type名称,值存储累加后的Type对象,遍历原始列表时判断键是否存在,存在则累加,不存在则新建对象存入Map。
// 假设你的Type类包含:getTypeName(), getAmount(), getQuantity(), setAmount(), setQuantity()方法 Map<String, Type> typeMap = new HashMap<>(); for (Type item : typeList) { String typeName = item.getTypeName(); if (typeMap.containsKey(typeName)) { // 已存在该类型,累加金额和数量 Type existingType = typeMap.get(typeName); existingType.setAmount(existingType.getAmount() + item.getAmount()); existingType.setQuantity(existingType.getQuantity() + item.getQuantity()); } else { // 不存在则新建对象存入Map(若需避免修改原对象,此处应创建副本) Type newType = new Type(); newType.setTypeName(typeName); newType.setAmount(item.getAmount()); newType.setQuantity(item.getQuantity()); typeMap.put(typeName, newType); } } // 将Map的值转换为列表,即为最终结果 List<Type> resultList = new ArrayList<>(typeMap.values());
方法二:使用Java 8+ Stream API(更简洁)
利用Stream的groupingBy分组,结合reducing实现累加逻辑:
List<Type> resultList = typeList.stream() .collect(Collectors.groupingBy( Type::getTypeName, Collectors.collectingAndThen( Collectors.reducing((t1, t2) -> { Type merged = new Type(); merged.setTypeName(t1.getTypeName()); merged.setAmount(t1.getAmount() + t2.getAmount()); merged.setQuantity(t1.getQuantity() + t2.getQuantity()); return merged; }), Optional::get ) )) .values() .stream() .collect(Collectors.toList());
注意事项
- 若
Type类有拷贝构造方法,创建副本时直接使用可简化代码; - 如需忽略大小写判断
Type名称,可在groupingBy中传入String::toLowerCase作为分类函数; - 处理浮点数累加时,为避免精度丢失,建议用
BigDecimal替代Double。
内容的提问来源于stack exchange,提问作者poojay
相关产品推荐
相关产品推荐

