如何用Java 8 Stream从两个对象列表中获取匹配对象对?
解决两个对象列表按条件匹配生成对象对的问题
你的当前代码存在问题:它只过滤出了存在匹配员工的公司,但并没有生成Pair<Company, Employee>对象对,最终收集的是List<Company>,和你想要的结果不符。下面给出几种正确的实现方式:
基础实现(小数据量场景)
直接通过嵌套流为每个公司匹配员工并生成Pair,适合数据量不大的情况:
import org.apache.commons.lang3.tuple.Pair; import java.util.List; import java.util.stream.Collectors; List<Pair<Company, Employee>> companyEmpPairList = companyList.stream() .flatMap(company -> empList.stream() // 按需求匹配:company.id 等于 employee.companyId(对应你代码里的emp.compId) .filter(emp -> company.getId() == emp.getCompanyId()) .map(emp -> Pair.of(company, emp)) ) .collect(Collectors.toList());
这里用flatMap替代filter,目的是把每个公司对应的匹配员工转换成Pair对象,再扁平化收集到同一个列表中。如果一个公司对应多个员工,会生成多个Pair;无匹配员工的公司则不会产生任何元素。
性能优化实现(大数据量场景)
嵌套流的时间复杂度是O(N*M),数据量大时效率很低。可以先把员工列表按companyId分组存入Map,之后直接通过Map查找匹配员工,时间复杂度降到O(N+M):
import org.apache.commons.lang3.tuple.Pair; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 先将员工按companyId分组 Map<Integer, List<Employee>> employeeByCompanyIdMap = empList.stream() .collect(Collectors.groupingBy(Employee::getCompanyId)); // 生成匹配的对象对 List<Pair<Company, Employee>> companyEmpPairList = companyList.stream() .flatMap(company -> employeeByCompanyIdMap.getOrDefault(company.getId(), List.of()) .stream() .map(emp -> Pair.of(company, emp)) ) .collect(Collectors.toList());
一对一匹配场景(可选)
如果你的业务是一个公司对应唯一员工,一个员工对应唯一公司,可以用toMap构建员工映射,再直接生成Pair:
import org.apache.commons.lang3.tuple.Pair; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 构建companyId到Employee的一对一映射 Map<Integer, Employee> employeeByCompanyIdMap = empList.stream() .collect(Collectors.toMap(Employee::getCompanyId, emp -> emp)); // 生成匹配对 List<Pair<Company, Employee>> companyEmpPairList = companyList.stream() .filter(company -> employeeByCompanyIdMap.containsKey(company.getId())) .map(company -> Pair.of(company, employeeByCompanyIdMap.get(company.getId()))) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Nilesh
相关产品推荐
相关产品推荐

