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实现存在三个核心问题:
- 仅处理了list2的元素,丢失了list1中不在list2内的元素
- 通过
peek直接修改了list1的原对象,不符合生成独立新列表的需求 - 代码存在变量名错误(
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
相关产品推荐
相关产品推荐

