如何将Java双层for-each循环转换为Stream流与Lambda函数实现
最优实现方案(推荐)
原有双层循环的时间复杂度为O(n*m),我们可以先将interviewResults预转为ID到结果的映射,将整体时间复杂度降至O(n+m),性能更好:
import java.util.stream.Collectors; import java.util.Map; // 原有查询逻辑不变 List<LightRecruiterScholarResponse> responses = eventScholarRepository.findScholarDetailsByEventId(eventId); List<InterviewDto> interviewResults = interviewRepository.getInterviewResultByRoundIdAndScholarId(); // 1. 构造学者ID到面试结果的映射,重复ID时保留先出现的结果,和原代码break逻辑完全一致 Map<String, String> interviewResultMap = interviewResults.stream() .collect(Collectors.toMap( InterviewDto::getId, InterviewDto::getInterviewResult, (oldVal, newVal) -> oldVal )); // 2. 批量填充面试状态 responses.forEach(response -> response.setInterviewStatus(interviewResultMap.get(response.getScholarId())) );
纯语法改写方案(仅做流替换,不优化性能)
如果你不需要优化性能,只是想把原有for循环完全替换为流写法,可以用嵌套流实现,该写法时间复杂度和原代码一致为O(n*m),仅适合小数据量场景:
responses.forEach(response -> { String status = interviewResults.stream() .filter(dto -> dto.getId().equals(response.getScholarId())) .findFirst() .map(InterviewDto::getInterviewResult) .orElse(null); response.setInterviewStatus(status); });
注意事项
- 如果
InterviewDto的id字段不是String类型,自行调整Map的key泛型即可 - 第一种方案的冲突保留策略
(oldVal, newVal) -> oldVal完全匹配原代码中匹配到第一个结果就break的逻辑,如果业务需要保留最新结果可以改成返回newVal
内容的提问来源于stack exchange,提问作者Sugata Kar
相关产品推荐
相关产品推荐

