如何通过Java Streams将分组结果转为自定义ResultSet对象列表
问题:将分组后的Map转换为ResultSet列表
已知有如下PivotMapEgModel对象列表:
List<PivotMapEgModel> pivotMapList = List.of( new PivotMapEgModel(1L, "1"), new PivotMapEgModel(1L, "2"), new PivotMapEgModel(1L, "3"), new PivotMapEgModel(2L, "5") );
定义了ResultSet类:
@Data @AllArgsConstructor class ResultSet { long value; String code_1; String code_2; String code_3; }
通过以下Stream分组后得到Map<Long, List<String>>:
Map<Long, List<String>> groupedMap = pivotMapList.stream() .collect(Collectors.groupingBy( PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList()) ));
输出结果为:{1=[1, 2, 3], 2=[5]}
需要将其转换为List<ResultSet>,期望输出:
[{value=1, code_1=1, code_2=2, code_3=3}, {value=2, code_1=5, code_2=null, code_3=null}]
(注:原问题期望输出中code_1写为1是笔误,应为5)
解决方案
可以通过对分组后的Map的entrySet进行流式处理,逐个将键值对转换为ResultSet对象,核心代码如下:
List<ResultSet> resultSetList = groupedMap.entrySet().stream() .map(entry -> { List<String> codes = entry.getValue(); // 按索引取对应code,不足3个的补null String code1 = codes.size() >= 1 ? codes.get(0) : null; String code2 = codes.size() >= 2 ? codes.get(1) : null; String code3 = codes.size() >= 3 ? codes.get(2) : null; return new ResultSet(entry.getKey(), code1, code2, code3); }) .collect(Collectors.toList());
代码说明:
- 对
groupedMap.entrySet()开启Stream,遍历每个键值对(key是value字段值,value是对应的code列表) - 在
map操作中,根据code列表的长度,分别取出第0、1、2位的元素,长度不足时赋值为null - 用当前key和取出的三个code创建
ResultSet对象 - 最后用
Collectors.toList()收集为List<ResultSet>
如果要把分组和转换合并成一步,可以直接链式调用:
List<ResultSet> resultSetList = pivotMapList.stream() .collect(Collectors.groupingBy( PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList()) )) .entrySet().stream() .map(entry -> { List<String> codes = entry.getValue(); String code1 = codes.size() >= 1 ? codes.get(0) : null; String code2 = codes.size() >= 2 ? codes.get(1) : null; String code3 = codes.size() >= 3 ? codes.get(2) : null; return new ResultSet(entry.getKey(), code1, code2, code3); }) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Vamsi
相关产品推荐
相关产品推荐

