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

Java中基于匹配键合并两个列表并生成指定结构类的求助

解决Java列表合并问题:将JuniorArea与Subgroup列表合并为预期结构

我来帮你搞定这个列表合并的问题!看起来你已经试过循环和Lambda表达式,但没得到想要的结果,咱们一步步拆解需求,写出符合预期的代码。

先明确需求

你需要把两个结构的数据合并:

  • List1 (juniorArea):键是区域描述(比如"One"、"Two"),值是对应的子组编码列表
  • List2:每个项包含子组编码和对应的产品列表
  • 预期输出:每个区域描述对应所有关联子组的产品集合,整理成指定的Java类结构

第一步:定义对应Java实体类

首先得创建和输入、输出结构匹配的实体类,这样才能正确存储和转换数据:

// 产品实体类,对应List2中的productGroup项
class Product {
    private String productCode;
    private String productDescription;

    // 构造器、Getter、Setter(必须补充,否则无法正常序列化/赋值)
    public Product(String productCode, String productDescription) {
        this.productCode = productCode;
        this.productDescription = productDescription;
    }

    public String getProductCode() { return productCode; }
    public void setProductCode(String productCode) { this.productCode = productCode; }
    public String getProductDescription() { return productDescription; }
    public void setProductDescription(String productDescription) { this.productDescription = productDescription; }
}

// List2中的子组实体类
class Subgroup {
    private String subgroupCode;
    private List<Product> productGroup;

    // 构造器、Getter、Setter
    public Subgroup(String subgroupCode, List<Product> productGroup) {
        this.subgroupCode = subgroupCode;
        this.productGroup = productGroup;
    }

    public String getSubgroupCode() { return subgroupCode; }
    public void setSubgroupCode(String subgroupCode) { this.subgroupCode = subgroupCode; }
    public List<Product> getProductGroup() { return productGroup; }
    public void setProductGroup(List<Product> productGroup) { this.productGroup = productGroup; }
}

// 预期输出中的区域项实体类
class JuniorAreaEntry {
    private String juniorAreaDescription;
    private List<Product> mechandisingGroup;

    public JuniorAreaEntry(String juniorAreaDescription, List<Product> mechandisingGroup) {
        this.juniorAreaDescription = juniorAreaDescription;
        this.mechandisingGroup = mechandisingGroup;
    }

    public String getJuniorAreaDescription() { return juniorAreaDescription; }
    public void setJuniorAreaDescription(String juniorAreaDescription) { this.juniorAreaDescription = juniorAreaDescription; }
    public List<Product> getMechandisingGroup() { return mechandisingGroup; }
    public void setMechandisingGroup(List<Product> mechandisingGroup) { this.mechandisingGroup = mechandisingGroup; }
}

// 最终结果的顶层实体类
class FinalResult {
    private List<JuniorAreaEntry> juniorArea;

    public FinalResult(List<JuniorAreaEntry> juniorArea) {
        this.juniorArea = juniorArea;
    }

    public List<JuniorAreaEntry> getJuniorArea() { return juniorArea; }
    public void setJuniorArea(List<JuniorAreaEntry> juniorArea) { this.juniorArea = juniorArea; }
}

第二步:核心合并逻辑

这里用Stream API实现,既简洁又高效,关键是先把List2转换成映射表,避免重复遍历:

import java.util.*;
import java.util.stream.Collectors;

public class ListMergeDemo {
    public static void main(String[] args) {
        // 模拟输入的juniorArea(List1)
        Map<String, List<String>> juniorArea = new HashMap<>();
        juniorArea.put("One", Collections.singletonList("G13DA"));
        juniorArea.put("Two", Arrays.asList("G13AA", "G13AD"));

        // 模拟输入的List2
        List<Subgroup> subgroupList = Arrays.asList(
                new Subgroup("G13AA", Arrays.asList(
                        new Product("G1A", "Two 1"),
                        new Product("G9B", "Two 2")
                )),
                new Subgroup("G13AD", Arrays.asList(
                        new Product("G4A", "Two 3"),
                        new Product("G9C", "Two 4")
                )),
                new Subgroup("G13DA", Arrays.asList(
                        new Product("G5M", "One 1"),
                        new Product("G9M", "One 2")
                ))
        );

        // 1. 把List2转成「子组编码->产品列表」的映射,O(1)快速查找
        Map<String, List<Product>> subgroupProductMap = subgroupList.stream()
                .collect(Collectors.toMap(
                        Subgroup::getSubgroupCode,
                        Subgroup::getProductGroup
                ));

        // 2. 遍历juniorArea,构建每个区域对应的产品集合
        List<JuniorAreaEntry> resultEntries = juniorArea.entrySet().stream()
                .map(entry -> {
                    String areaDesc = entry.getKey();
                    List<String> subgroupCodes = entry.getValue();

                    // 收集所有关联子组的产品,合并成一个列表
                    List<Product> mergedProducts = subgroupCodes.stream()
                            .map(subgroupProductMap::get) // 根据子组编码拿产品列表
                            .filter(Objects::nonNull) // 防止子组编码在List2中不存在的情况
                            .flatMap(List::stream) // 把多个列表扁平化成单个产品流
                            .collect(Collectors.toList());

                    return new JuniorAreaEntry(areaDesc, mergedProducts);
                })
                .collect(Collectors.toList());

        // 3. 构建最终结果对象
        FinalResult finalResult = new FinalResult(resultEntries);

        // 验证输出(可以用Jackson转成JSON查看是否符合预期)
        // com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
        // System.out.println(mapper.writeValueAsString(finalResult));
    }
}

关键逻辑说明

  • 构建映射表:把List2转成Map<String, List<Product>>,这样每次查找子组对应的产品只需要O(1)时间,比嵌套遍历List2的O(n*m)效率高很多,尤其是数据量大的时候。
  • flatMap合并列表:用flatMap把多个子组的产品列表合并成一个,避免出现嵌套列表的问题(这可能是你之前尝试Lambda没成功的原因)。
  • 空值过滤:filter(Objects::nonNull)处理子组编码在List2中不存在的情况,防止出现NullPointerException。

如果你需要用循环实现,逻辑也是一样的:先构建映射表,然后遍历juniorArea的每个项,逐个取出子组对应的产品合并即可。

内容的提问来源于stack exchange,提问作者Emraan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:56:30