You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何递归合并包含同类型内部列表的Java Item对象列表?

递归合并重复ID的Item列表实现方案

针对你的需求,我们可以通过按ID分组+递归合并的方式处理所有层级的重复Item,核心思路是先处理当前层级的重复项,再递归处理子Item列表的重复。以下是具体实现:

合并逻辑说明

  1. 层级分组:将当前层级的Item按id分组,同一ID的Item归为一组。
  2. 同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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:35:32