如何用Java8风格高效实现List<Map>向目标结构的转换
Java 8 高效转换 List<Map<String, Object>> 到指定结构
刚好之前也处理过类似的需求,用Java 8的Stream API完全可以做到无嵌套循环的高效转换,结合收集器的能力,代码简洁还能保证性能。下面是参考了Maurice Perry的思路后优化出的最终解决方案:
先明确场景(可根据你的实际结构调整)
先假设一组示例数据,方便你对应自己的业务场景:
- 原数据集(JSON形式展示):
[ {"id": 1, "category": "A", "name": "Item1", "value": 100}, {"id": 2, "category": "A", "name": "Item2", "value": 200}, {"id": 3, "category": "B", "name": "Item3", "value": 150} ]
- 目标结构:按
category分组,每个分组包含分类名和对应子项列表(你可以根据实际需求修改字段和结构):
[ {"category": "A", "items": [{"name": "Item1", "value": 100}, {"name": "Item2", "value": 200}]}, {"category": "B", "items": [{"name": "Item3", "value": 150}]} ]
最终实现代码
import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class DataConverter { public static List<Map<String, Object>> convertOriginalData(List<Map<String, Object>> originalData) { return originalData.stream() // 第一步:按指定字段(这里是category)完成分组,替代手动嵌套循环分组 .collect(Collectors.groupingBy(item -> (String) item.get("category"))) // 第二步:将分组后的键值对转换为目标结构的Map .entrySet().stream() .map(entry -> { // 处理子项列表:提取原数据中需要的字段 List<Map<String, Object>> subItems = entry.getValue().stream() .map(item -> { // Java 8 用HashMap创建,Java 9+可以用Map.of()简化 Map<String, Object> subMap = new HashMap<>(); subMap.put("name", item.get("name")); subMap.put("value", item.get("value")); return subMap; }) .collect(Collectors.toList()); // 构建最终的目标Map Map<String, Object> targetMap = new HashMap<>(); targetMap.put("category", entry.getKey()); targetMap.put("items", subItems); return targetMap; }) .collect(Collectors.toList()); } }
关键细节说明
- 无嵌套循环的核心:用
Collectors.groupingBy一次性完成分组操作,替代了传统的“遍历-判断-分组”嵌套逻辑,底层实现经过优化,性能更优。 - Stream链式操作:整个转换过程通过Stream的链式调用完成,代码线性可读,没有多层嵌套,维护起来更轻松。
- 灵活调整:如果你的目标结构不需要分组,直接在原数据的Stream上做
map转换即可;如果需要聚合统计(比如求和、计数),可以结合Collectors.summingInt、Collectors.counting等收集器在分组阶段完成。 - 并行优化(可选):如果原数据集数据量很大,可以把
stream()换成parallelStream(),利用多线程提升处理速度,注意如果原集合是线程不安全的,要提前做好处理。
内容的提问来源于stack exchange,提问作者yglodt
相关产品推荐
相关产品推荐

