如何合并EmployeeDetails与EmployeeSalary集合,生成含联合属性的新集合
合并EmployeeDetails和EmployeeSalary列表的解决方案
我来帮你搞定这个员工数据合并的需求!首先咱们得先准备一个能容纳合并后数据的实体类,然后再用合适的方法把两个列表的内容对应起来。
第一步:创建合并后的实体类
先定义一个EmployeeCombined类,包含你需要的三个属性:id、name和salary,并生成对应的getter和setter方法(可选构造器和toString方法,方便后续使用):
public class EmployeeCombined { private String id; private String name; private String salary; // 构造器,快速创建对象 public EmployeeCombined(String id, String name, String salary) { this.id = id; this.name = name; this.salary = salary; } // Getter和Setter方法 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSalary() { return salary; } public void setSalary(String salary) { this.salary = salary; } // 重写toString,方便打印查看结果 @Override public String toString() { return "EmployeeCombined{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", salary='" + salary + '\'' + '}'; } }
第二步:选择合适的合并方法
方法一:传统循环遍历(适合Java 8以下版本)
这种方法逻辑直观,新手也能快速理解。遍历EmployeeDetails列表,逐个在EmployeeSalary列表中匹配对应id的薪资数据,找到后创建合并对象:
import java.util.ArrayList; import java.util.List; public class MergeEmployeeData { public static void main(String[] args) { // 模拟测试数据 List<EmployeeDetails> detailsList = new ArrayList<>(); detailsList.add(createEmployeeDetail("E001", "Alice")); detailsList.add(createEmployeeDetail("E002", "Bob")); List<EmployeeSalary> salaryList = new ArrayList<>(); salaryList.add(createEmployeeSalary("E001", "8000")); salaryList.add(createEmployeeSalary("E002", "9500")); // 初始化合并后的列表 List<EmployeeCombined> combinedList = new ArrayList<>(); for (EmployeeDetails detail : detailsList) { String empId = detail.getId(); // 遍历薪资列表找对应id for (EmployeeSalary salary : salaryList) { if (empId.equals(salary.getId())) { combinedList.add(new EmployeeCombined(empId, detail.getName(), salary.getSal())); break; // 找到就跳出内层循环,节省时间 } } } // 打印合并结果 combinedList.forEach(System.out::println); } // 辅助方法,简化测试对象创建 private static EmployeeDetails createEmployeeDetail(String id, String name) { EmployeeDetails detail = new EmployeeDetails(); detail.setId(id); detail.setName(name); return detail; } private static EmployeeSalary createEmployeeSalary(String id, String sal) { EmployeeSalary salary = new EmployeeSalary(); salary.setId(id); salary.setSal(sal); return salary; } }
注意:这种方法的时间复杂度是O(n*m),如果两个列表数据量很大,效率会比较低。
方法二:Map+Stream API(Java 8及以上,高效优雅)
先把EmployeeSalary列表转成以id为key、sal为value的Map,这样查找薪资的时间复杂度直接降到O(1),整体效率提升到O(n+m),代码也更简洁:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class MergeEmployeeDataWithStream { public static void main(String[] args) { // 模拟测试数据(包含部分不匹配的情况) List<EmployeeDetails> detailsList = new ArrayList<>(); detailsList.add(createEmployeeDetail("E001", "Alice")); detailsList.add(createEmployeeDetail("E002", "Bob")); detailsList.add(createEmployeeDetail("E003", "Charlie")); // 无对应薪资 List<EmployeeSalary> salaryList = new ArrayList<>(); salaryList.add(createEmployeeSalary("E001", "8000")); salaryList.add(createEmployeeSalary("E002", "9500")); salaryList.add(createEmployeeSalary("E004", "7500")); // 无对应员工详情 // 把薪资列表转成Map:key=员工id,value=薪资 Map<String, String> salaryMap = salaryList.stream() .collect(Collectors.toMap(EmployeeSalary::getId, EmployeeSalary::getSal)); // 合并数据,同时处理无匹配的情况 List<EmployeeCombined> combinedList = detailsList.stream() .map(detail -> { // 找不到薪资时设置默认值 String salary = salaryMap.getOrDefault(detail.getId(), "无薪资数据"); return new EmployeeCombined(detail.getId(), detail.getName(), salary); }) .collect(Collectors.toList()); // 打印结果 combinedList.forEach(System.out::println); } // 辅助方法和之前一致 private static EmployeeDetails createEmployeeDetail(String id, String name) { EmployeeDetails detail = new EmployeeDetails(); detail.setId(id); detail.setName(name); return detail; } private static EmployeeSalary createEmployeeSalary(String id, String sal) { EmployeeSalary salary = new EmployeeSalary(); salary.setId(id); salary.setSal(sal); return salary; } }
这种方法还能轻松处理数据不匹配的场景,比如有的员工没有薪资记录,用getOrDefault就能给缺失的数据设置默认值。
额外扩展:包含所有员工(含单向匹配的情况)
如果你想把两边不匹配的数据也纳入结果(比如只有薪资没有详情的员工),可以先收集所有唯一的员工id,再逐个匹配详情和薪资:
import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; // 接上面的代码,在main方法中添加: Set<String> allEmpIds = new HashSet<>(); allEmpIds.addAll(detailsList.stream().map(EmployeeDetails::getId).collect(Collectors.toList())); allEmpIds.addAll(salaryList.stream().map(EmployeeSalary::getId).collect(Collectors.toList())); List<EmployeeCombined> fullCombinedList = allEmpIds.stream() .map(id -> { // 查找姓名,找不到设默认值 String name = detailsList.stream() .filter(d -> d.getId().equals(id)) .map(EmployeeDetails::getName) .findFirst() .orElse("无姓名数据"); // 查找薪资,找不到设默认值 String salary = salaryMap.getOrDefault(id, "无薪资数据"); return new EmployeeCombined(id, name, salary); }) .collect(Collectors.toList()); // 打印完整结果 fullCombinedList.forEach(System.out::println);
内容的提问来源于stack exchange,提问作者prem
相关产品推荐
相关产品推荐

