Java如何实现集合元素按公共属性分组并对同组数值求和
实现方案
首先假设你的集合元素对应实体类如下:
// 元素实体类示例 public class Item { private Integer id; private Integer quantity; public Item(Integer id, Integer quantity) { this.id = id; this.quantity = quantity; } // getter方法 public Integer getId() { return id; } public Integer getQuantity() { return quantity; } }
方案1:Java 8+ Stream API实现(推荐)
用Stream自带的分组归集器直接实现,代码简洁高效:
import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class GroupSumDemo { public static void main(String[] args) { // 原始集合示例 List<Item> originList = List.of( new Item(18, 20), new Item(18, 70), new Item(21, 50) ); // 按id分组累加quantity,得到id对应总和的Map Map<Integer, Integer> sumResultMap = originList.stream() .collect(Collectors.groupingBy( Item::getId, // 分组key:取id Collectors.summingInt(Item::getQuantity) // 分组后求和:累加quantity )); // 如果需要转回Item类型的结果集合 List<Item> resultList = sumResultMap.entrySet().stream() .map(entry -> new Item(entry.getKey(), entry.getValue())) .toList(); // JDK16以下替换为.collect(Collectors.toList()) // 输出验证 resultList.forEach(item -> System.out.printf("id:%d quantity:%d%n", item.getId(), item.getQuantity()) ); } }
如果需要保留原始集合的id出现顺序,可以指定用LinkedHashMap存储分组结果:
Map<Integer, Integer> sumResultMap = originList.stream() .collect(Collectors.groupingBy( Item::getId, java.util.LinkedHashMap::new, // 有序Map存储,保留id出现顺序 Collectors.summingInt(Item::getQuantity) ));
方案2:普通遍历实现(兼容JDK 8以下版本)
如果项目使用的JDK版本低于8,用普通遍历+HashMap实现:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class GroupSumDemo { public static void main(String[] args) { List<Item> originList = new ArrayList<>(); originList.add(new Item(18, 20)); originList.add(new Item(18, 70)); originList.add(new Item(21, 50)); Map<Integer, Integer> sumMap = new HashMap<>(); // 遍历累加 for (Item item : originList) { Integer id = item.getId(); Integer quantity = item.getQuantity(); // JDK8以下没有getOrDefault可以用if判断替换 sumMap.put(id, sumMap.getOrDefault(id, 0) + quantity); /* JDK8以下写法 if (sumMap.containsKey(id)) { sumMap.put(id, sumMap.get(id) + quantity); } else { sumMap.put(id, quantity); } */ } // 转回Item集合 List<Item> resultList = new ArrayList<>(); for (Map.Entry<Integer, Integer> entry : sumMap.entrySet()) { resultList.add(new Item(entry.getKey(), entry.getValue())); } // 输出验证 for (Item item : resultList) { System.out.printf("id:%d quantity:%d%n", item.getId(), item.getQuantity()); } } }
内容的提问来源于stack exchange,提问作者user11888222
相关产品推荐
相关产品推荐

