如何递归合并包含同类型内部列表的Java Item对象列表?
递归合并重复ID的Item列表实现方案
针对你的需求,我们可以通过按ID分组+递归合并的方式处理所有层级的重复Item,核心思路是先处理当前层级的重复项,再递归处理子Item列表的重复。以下是具体实现:
合并逻辑说明
- 层级分组:将当前层级的Item按
id分组,同一ID的Item归为一组。 - 同ID项合并:
- 基础属性(
id/name):以组内第一个Item的属性为基准(若需校验name一致性可额外添加逻辑)。 result合并:将所有同ID项的result键值对合并,重复键以后续项的取值覆盖(或按需改为累加)。- 子Item合并:收集所有同ID项的子Item列表,递归调用合并方法处理子层级重复,再赋值给合并后的Item。
- 基础属性(
代码实现
import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ItemMerger { // 递归合并Item列表,处理所有层级的重复ID public static List<Item> mergeItems(List<Item> items) { if (items == null || items.isEmpty()) { return new ArrayList<>(); } // 按ID分组,聚合同一ID的所有Item Map<String, List<Item>> groupedById = items.stream() .collect(Collectors.groupingBy(Item::getId)); List<Item> mergedItems = new ArrayList<>(); for (Map.Entry<String, List<Item>> entry : groupedById.entrySet()) { mergedItems.add(mergeSameIdItems(entry.getValue())); } return mergedItems; } // 合并同一ID下的多个Item private static Item mergeSameIdItems(List<Item> sameIdItems) { if (sameIdItems == null || sameIdItems.isEmpty()) { return null; } Item merged = new Item(); Item baseItem = sameIdItems.get(0); merged.setId(baseItem.getId()); merged.setName(baseItem.getName()); // 校验同ID项的name是否一致(可选,按需开启) // String standardName = baseItem.getName(); // for (Item item : sameIdItems) { // if (!standardName.equals(item.getName())) { // throw new IllegalArgumentException("ID为" + baseItem.getId() + "的Item存在名称冲突:" + standardName + " vs " + item.getName()); // } // } // 合并result:后续项的重复键覆盖前面的 LinkedHashMap<String, Integer> mergedResult = new LinkedHashMap<>(); for (Item item : sameIdItems) { if (item.getResult() != null) { mergedResult.putAll(item.getResult()); } } merged.setResult(mergedResult.isEmpty() ? null : mergedResult); // 收集所有子Item并递归合并 List<Item> allChildItems = new ArrayList<>(); for (Item item : sameIdItems) { if (item.getItems() != null && !item.getItems().isEmpty()) { allChildItems.addAll(item.getItems()); } } List<Item> mergedChildItems = mergeItems(allChildItems); merged.setItems(mergedChildItems.isEmpty() ? null : mergedChildItems); return merged; } }
使用示例
// 假设originalItems是待合并的Item列表 List<Item> mergedItems = ItemMerger.mergeItems(originalItems);
可选调整项
- Result累加逻辑:若需要对重复键的数值进行累加而非覆盖,修改
result合并部分为:for (Item item : sameIdItems) { if (item.getResult() != null) { item.getResult().forEach((key, value) -> mergedResult.merge(key, value, Integer::sum) ); } } - 空值处理:代码已适配实体类的
@JsonInclude(NON_NULL)注解,合并后空的result或items会被设为null。
内容的提问来源于stack exchange,提问作者Simon Symhoven
相关产品推荐
相关产品推荐

