Java8根据ID移除List元素并收集被移除元素到另一列表
Java 8 按ID匹配拆分Employee列表实现方案
需求梳理
- 输入为两个存储
Employee类型对象的列表list1、list2 - 匹配规则:以
Employee对象的id属性为匹配依据,匹配时忽略大小写 - 处理规则:从
list1中移除所有id未在list2中存在的元素,所有被移除的元素存入新列表list3
原有代码问题
你写的实现逻辑存在3个核心错误,所以结果不符合预期:
- 遍历方向错误:以
list2为遍历基准,会把list2独有的id纳入无效判断,逻辑完全颠倒 - 判断逻辑错误:每次遍历list2元素时,只要找到任意一个id和当前list2元素id不等的list1元素就判定为待移除,判断条件完全不成立
- 性能差且有风险:遍历过程中反复全表扫描list1、多次调用
removeIf修改列表,时间复杂度高,还可能触发并发修改异常
正确实现思路
- 先提取
list2中所有员工的id,统一转为小写后存入HashSet,后续id匹配的时间复杂度可以从O(n)降到O(1) - 直接调用
list1的removeIf方法做批量处理:对每个list1元素判断id是否在提前准备的id集合中,不在的话就先把元素加入list3,再返回true将该元素从list1中移除 - 提前做空判断,避免空指针异常,不需要额外引入第三方工具类
完整可运行代码
import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; // Employee实体类,没有用Lombok的话手动补全getter、全参构造、toString方法即可 class Employee { private String id; private String city; private String state; public Employee(String id, String city, String state) { this.id = id; this.city = city; this.state = state; } public String getId() { return id; } @Override public String toString() { return "Employee{" + "id='" + id + '\'' + ", city='" + city + '\'' + ", state='" + state + '\'' + '}'; } } public class EmployeeListProcess { public static void main(String[] args) { // 示例输入list1 List<Employee> list1 = Stream.of( new Employee("100","Boston","Massachusetts"), new Employee("400","Atlanta","Georgia"), new Employee("300","pleasanton","California"), new Employee("200","Decatur","Texas"), new Employee("500","Cumming","Atlanta"), new Employee("98","sula","Maine"), new Employee("156","Duluth","Ohio")) .collect(Collectors.toList()); // 匹配基准list2 List<Employee> list2 = Stream.of( new Employee("100","Boston","Massachusetts"), new Employee("800","pleasanton","California"), new Employee("400","Atlanta","Georgia"), new Employee("10","Decatur","Texas"), new Employee("500","Cumming","Atlanta"), new Employee("50","sula","Maine"), new Employee("156","Duluth","Ohio")) .collect(Collectors.toList()); // 核心处理逻辑 List<Employee> list3 = new ArrayList<>(); if (list1 != null && !list1.isEmpty() && list2 != null && !list2.isEmpty()) { // 预收集list2的所有id,统一转小写实现忽略大小写匹配 Set<String> existIds = list2.stream() .map(emp -> emp.getId().toLowerCase(Locale.ROOT)) .collect(Collectors.toSet()); // 批量移除不匹配元素,移除前同步收集到list3 list1.removeIf(emp -> { boolean needRemove = !existIds.contains(emp.getId().toLowerCase(Locale.ROOT)); if (needRemove) { list3.add(emp); } return needRemove; }); } // 结果输出验证 System.out.println("处理后list1:"); list1.forEach(System.out::println); System.out.println("\n被移除的元素list3:"); list3.forEach(System.out::println); } }
运行结果说明
代码运行后完全符合预期输出:
- 处理后的
list1保留id为100、400、500、156的4条员工数据 list3存储被移除的id为300、200、98的3条员工数据
内容的提问来源于stack exchange,提问作者Musa
相关产品推荐
相关产品推荐

