Java使用lambda实现QuestionEventDTO查询结果分组合并为列表
Java数据库查询结果分组聚合实现方案
实现思路
通过JDK Stream内置分组能力,两层分组分别聚合QuestionEvent和对应Question的选项,核心依赖Collectors.groupingBy收集器完成分组,再手动组装目标结构即可,对lambda熟练度要求低。
前置说明
你的RowMapper中用到的QuestionOptionDTO和提前定义的OptionDTO属于同一类的笔误,以下代码默认按照OptionDTO处理。
完整实现代码
import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 这里替换为你实际调用存储过程拿到的原始结果 List<QuestionEventDTO> rawList = jdbcTemplate.query("你的存储过程调用语句", new QuestionEventMapper()); // 第一层分组:按QuestionEvent的id分组,key为事件id,value为同个事件对应的所有原始返回行 Map<Long, List<QuestionEventDTO>> eventGroup = rawList.stream() .collect(Collectors.groupingBy(QuestionEventDTO::getId)); // 遍历分组组装成目标结构 List<QuestionEventDTO> targetResult = eventGroup.entrySet().stream() .map(eventEntry -> { Long eventId = eventEntry.getKey(); List<QuestionEventDTO> sameEventRows = eventEntry.getValue(); // 第二层分组:同个事件下按Question的id分组,收集该问题对应的所有选项 Map<Long, List<OptionDTO>> questionGroup = sameEventRows.stream() .collect(Collectors.groupingBy( row -> row.getQuestion().getId(), Collectors.mapping(row -> row.getQuestion().getOption(), Collectors.toList()) )); // 组装QuestionDTO列表 List<QuestionDTO> questions = questionGroup.entrySet().stream() .map(qEntry -> new QuestionDTO(qEntry.getKey(), null, qEntry.getValue())) .collect(Collectors.toList()); // 组装最终返回的QuestionEventDTO return new QuestionEventDTO(eventId, null, questions); }) .collect(Collectors.toList());
逻辑说明
- 第一层分组解决同一个事件返回多行的问题,把相同事件id的所有行归为一组
- 第二层分组解决同一个问题对应多个选项的问题,把相同问题id的所有选项收集为列表
- 最终组装严格匹配你要求的结构:事件的
question字段设为null,questions字段存放组装好的问题列表;每个问题的option字段设为null,options字段存放收集到的所有选项
场景适配提示
如果你的业务场景下同一个事件只会对应一个问题,可以在组装时直接取question列表的第一个元素,不需要保留列表结构,调整组装逻辑即可。
内容的提问来源于stack exchange,提问作者Romeu Fernandes Bessa
相关产品推荐
相关产品推荐

