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

Java8中合并并更新AObj对象列表的实现问题

Java 实现两个AObj列表的合并更新逻辑

AObj类定义

public class AObj
{
    private String name;
    private String code;
    private String value;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return this.code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getValue() {
        return this.value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

合并需求

  • 若list2中的元素在list1中不存在(以code作为唯一标识),则将该元素添加到新列表
  • 若list2中的元素在list1中已存在,则仅更新list1中对应元素的变化属性,保留未变化的属性

示例说明

原始列表

// list1初始数据
ArrayList<AObj> list1 = new ArrayList<>(List.of(
    new AObj() {{ setName("a"); setCode("1"); setValue("a"); }},
    new AObj() {{ setName("b"); setCode("2"); setValue("ss"); }},
    new AObj() {{ setName("c"); setCode("5"); setValue("c"); }}
));

// list2数据
ArrayList<AObj> list2 = new ArrayList<>(List.of(
    new AObj() {{ setName("b"); setCode("2"); setValue("l2"); }},
    new AObj() {{ setName("d"); setCode("6"); setValue("c7"); }}
));

合并后目标列表

ArrayList<AObj> list3 = new ArrayList<>(List.of(
    new AObj() {{ setName("a"); setCode("1"); setValue("a"); }},
    new AObj() {{ setName("b"); setCode("2"); setValue("l2"); }}, // value属性被更新
    new AObj() {{ setName("c"); setCode("5"); setValue("c"); }},
    new AObj() {{ setName("d"); setCode("6"); setValue("c7"); }} // 新增元素
));

问题分析

你之前的Stream实现存在三个核心问题:

  1. 仅处理了list2的元素,丢失了list1中不在list2内的元素
  2. 通过peek直接修改了list1的原对象,不符合生成独立新列表的需求
  3. 代码存在变量名错误(consent应为l1)

正确实现方案

高效实现(基于Map)

通过Map快速查找元素,同时创建对象副本避免修改原始数据,时间复杂度优化为O(n+m):

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ListMergeExample {
    public static void main(String[] args) {
        // 初始化list1
        List<AObj> list1 = new ArrayList<>();
        AObj obj1 = new AObj();
        obj1.setName("a");
        obj1.setCode("1");
        obj1.setValue("a");
        list1.add(obj1);

        AObj obj2 = new AObj();
        obj2.setName("b");
        obj2.setCode("2");
        obj2.setValue("ss");
        list1.add(obj2);

        AObj obj3 = new AObj();
        obj3.setName("c");
        obj3.setCode("5");
        obj3.setValue("c");
        list1.add(obj3);

        // 初始化list2
        List<AObj> list2 = new ArrayList<>();
        AObj obj4 = new AObj();
        obj4.setName("b");
        obj4.setCode("2");
        obj4.setValue("l2");
        list2.add(obj4);

        AObj obj5 = new AObj();
        obj5.setName("d");
        obj5.setCode("6");
        obj5.setValue("c7");
        list2.add(obj5);

        // 执行合并
        List<AObj> mergedList = mergeLists(list1, list2);
        // 打印验证结果
        mergedList.forEach(obj -> System.out.printf("name='%s', code='%s', value='%s'%n", 
                                                    obj.getName(), obj.getCode(), obj.getValue()));
    }

    private static List<AObj> mergeLists(List<AObj> list1, List<AObj> list2) {
        // 将list1元素复制到Map,避免修改原对象
        Map<String, AObj> codeToObjMap = list1.stream()
                .map(ListMergeExample::copyAObj)
                .collect(Collectors.toMap(AObj::getCode, obj -> obj));

        // 处理list2元素
        list2.forEach(list2Obj -> {
            AObj existingObj = codeToObjMap.get(list2Obj.getCode());
            if (existingObj != null) {
                // 仅更新变化的属性
                if (!list2Obj.getName().equals(existingObj.getName())) {
                    existingObj.setName(list2Obj.getName());
                }
                if (!list2Obj.getValue().equals(existingObj.getValue())) {
                    existingObj.setValue(list2Obj.getValue());
                }
            } else {
                // 新增元素,同样存入副本
                codeToObjMap.put(list2Obj.getCode(), copyAObj(list2Obj));
            }
        });

        return new ArrayList<>(codeToObjMap.values());
    }

    // 创建AObj副本,隔离原对象与合并后的列表
    private static AObj copyAObj(AObj source) {
        AObj copy = new AObj();
        copy.setName(source.getName());
        copy.setCode(source.getCode());
        copy.setValue(source.getValue());
        return copy;
    }
}

纯Stream简化实现

如果偏好Stream风格,可通过Collectors.toMap的合并函数实现:

private static List<AObj> mergeListsWithStream(List<AObj> list1, List<AObj> list2) {
    Map<String, AObj> mergedMap = Stream.concat(list1.stream(), list2.stream())
            .map(ListMergeExample::copyAObj)
            .collect(Collectors.toMap(
                    AObj::getCode,
                    obj -> obj,
                    (existing, newObj) -> {
                        // 合并逻辑:仅更新变化的属性
                        if (!newObj.getName().equals(existing.getName())) {
                            existing.setName(newObj.getName());
                        }
                        if (!newObj.getValue().equals(existing.getValue())) {
                            existing.setValue(newObj.getValue());
                        }
                        return existing;
                    }
            ));
    return new ArrayList<>(mergedMap.values());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:34:57