Java8如何遍历嵌套SubQuestion列表匹配指定questionId
Java8 实现方案
优化后两层查找代码(匹配你的需求)
你的现有代码逻辑是通顺的,我们可以做几处优化规避空指针、减少不必要性能开销:
Long targetQuestionId = dto.getQuestions().get(0).getQuestionId(); SubQuestion subQuestion = questionDetails.getSubQuestions().stream() // 匹配第一层subQuestion .filter(sub -> targetQuestionId.equals(sub.getQuestionId())) .findAny() // 第一层无匹配时再执行第二层查找逻辑,用orElseGet避免提前执行无意义遍历 .orElseGet(() -> questionDetails.getSubQuestions().stream() .flatMap(sub -> sub.getChildQuestions() == null ? Stream.empty() : sub.getChildQuestions().stream()) // 匹配第二层childQuestion .filter(child -> targetQuestionId.equals(child.getQuestionId())) .findFirst() .orElse(null) );
优化点说明
- 去掉了重复创建
Long对象的逻辑,直接用Long类型的equals方法比较即可,避免不必要的对象创建开销 - 新增了
childQuestions的空判断,避免子问题列表为空时触发空指针异常 - 把原来的
orElse改为orElseGet,只有第一层没有匹配结果时才会执行第二层的遍历逻辑,不会做多余计算 - 注意你原有代码中同时出现了
questionDetails和questionDetailsDTO两个不同对象,需确认是否为笔误,上面代码统一按数据源为questionDetails调整
支持无限层级嵌套的通用实现
如果后续SubQuestion的子层级可能超过2层,可以抽成递归通用方法:
private Optional<SubQuestion> findSubQuestionById(List<SubQuestion> subQuestionList, Long targetQuestionId) { // 列表为空直接返回空 if (subQuestionList == null || subQuestionList.isEmpty()) { return Optional.empty(); } // 先匹配当前层级 Optional<SubQuestion> currentMatch = subQuestionList.stream() .filter(sub -> targetQuestionId.equals(sub.getQuestionId())) .findAny(); if (currentMatch.isPresent()) { return currentMatch; } // 递归遍历所有子层级查找 return subQuestionList.stream() .flatMap(sub -> findSubQuestionById(sub.getChildQuestions(), targetQuestionId).stream()) .findFirst(); }
调用方式:
Long targetQuestionId = dto.getQuestions().get(0).getQuestionId(); SubQuestion subQuestion = findSubQuestionById(questionDetails.getSubQuestions(), targetQuestionId).orElse(null);
内容的提问来源于stack exchange,提问作者Siva Sai kiran
相关产品推荐
相关产品推荐

