Java合并两个MyObject列表 按id去重保留isLatest非空元素
实现方案说明
注意你当前提供的实现修改了
MyObject的相等判断逻辑,仅将id作为equals和hashCode的生成依据,违反了「原有equals()和hashCode()基于id、firstProp、secondProp三个字段生成、不可修改」的约束,会影响其他依赖原有相等逻辑的业务模块,不建议在生产环境使用。
推荐的最优实现方案
核心思路是用id作为键构建中间映射表,优先存储isLatest非空的元素,再补充不存在的isLatest为空的元素,时间复杂度为O(n+m)(n、m为两个列表的长度),完全不修改原有类的逻辑,符合所有约束:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class MergeListTest { public static void main(String[] args) { List<MyObject> listWithIsLatestSet = getListWithIsLatestSet(); List<MyObject> listWithIsLatestNull = getListWithIsLatestNull(); // 1. 构建id到对象的映射表,先存入所有isLatest非空的元素 Map<Long, MyObject> idObjMap = new HashMap<>(); listWithIsLatestSet.forEach(obj -> idObjMap.put(obj.getId(), obj)); // 2. 遍历isLatest为空的列表,仅存入id不在映射表中的元素 listWithIsLatestNull.forEach(obj -> { if (!idObjMap.containsKey(obj.getId())) { idObjMap.put(obj.getId(), obj); } }); // 3. 按需转为List或Set List<MyObject> mergedList = new ArrayList<>(idObjMap.values()); // 如果需要Set可以用:Set<MyObject> mergedSet = new HashSet<>(idObjMap.values()); // 输出验证 mergedList.forEach(System.out::println); } // 原有获取列表的方法,MyObject类使用业务原有定义,不修改任何注解 private static List<MyObject> getListWithIsLatestSet() { // 构造逻辑和你的示例一致,此处省略实现 } private static List<MyObject> getListWithIsLatestNull() { // 构造逻辑和你的示例一致,此处省略实现 } } // 业务原有定义的MyObject,完全不做修改 class MyObject { private Long id; private String firstProp; private String secondProp; private Boolean isLatest; // 原有getter、setter、equals、hashCode方法保持不变 public Long getId() { return id; } // 其他原有方法省略 }
方案优势
- 完全符合业务约束:没有修改
MyObject的任何原有逻辑,不会影响其他模块功能 - 执行效率高:线性时间复杂度,远高于双重循环比对的O(n*m)方案
- 逻辑清晰易维护:步骤拆分明确,后续调整去重或者优先级规则修改成本低
- 灵活性高:最终结果可以自由选择转为
List或者Set,适配不同业务场景
如果偏好Stream流式写法,也可以用Collectors.toMap实现等价逻辑,写法更简洁:
List<MyObject> mergedList = Stream.concat(listWithIsLatestSet.stream(), listWithIsLatestNull.stream()) .collect(Collectors.toMap( MyObject::getId, obj -> obj, // 冲突时保留先出现的元素(非空列表在前,所以会自动保留非空元素) (oldVal, newVal) -> oldVal )) .values() .stream() .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者curious_brain
相关产品推荐
相关产品推荐

