如何使用Java Stream API实现嵌套Map的扁平化与键拼接?
使用Java Stream API实现嵌套Map的扁平化与键拼接
你已经用普通循环和递归实现了嵌套Map的扁平化,现在想用Stream API来完成这个需求对吧?其实我们可以结合递归流生成和flatMap来实现,既保持代码简洁,又能处理任意深度的嵌套结构。
实现思路
核心逻辑和递归方案一致,但用Stream的链式操作重构:
- 遍历每个Map条目,判断值的类型
- 如果是子Map,递归处理并将当前键作为前缀拼接
- 如果是普通值,直接生成拼接好的键值对
- 用
flatMap把递归产生的流逐层展开,最后收集为目标Map
完整实现代码
import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; public class MapFlattener { // 对外暴露的扁平化入口方法 public static Map<String, String> flatWithStream(Map<String, Object> input) { return flattenStream(input, "") .collect(HashMap::new, (resultMap, entry) -> resultMap.put(entry.getKey(), entry.getValue()), HashMap::putAll); } // 递归生成扁平化的键值对流 private static Stream<Map.Entry<String, String>> flattenStream(Map<String, Object> map, String prefix) { return map.entrySet().stream() .flatMap(entry -> { // 计算新的键前缀:顶层Map直接用当前键,嵌套时拼接前缀 String newPrefix = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey(); if (entry.getValue() instanceof Map<?, ?>) { // 递归处理子Map,安全转换类型 @SuppressWarnings("unchecked") Map<String, Object> subMap = (Map<String, Object>) entry.getValue(); return flattenStream(subMap, newPrefix); } else { // 普通值,生成最终的键值对条目 return Stream.of(Map.entry(newPrefix, entry.getValue().toString())); } }); } // 测试用例 public static void main(String[] args) { Map<String,Object> map = new HashMap<>(); Map<String,Object> map1 = new HashMap<>(); map1.put("key1", "value1"); Map<String,Object> map2 = new HashMap<>(); Map<String,Object> map3 = new HashMap<>(); map3.put("key2", "value2"); map2.put("map3", map3); map.put("map1", map1); map.put("map2", map2); map.put("key3", "value3"); Map<String, String> flattened = flatWithStream(map); flattened.forEach((k, v) -> System.out.printf("[%s, %s]%n", k, v)); } }
代码细节解释
flatWithStream方法:作为对外接口,调用递归流方法后,通过collect将流收集为HashMap,指定了初始化、累加和合并的逻辑。flattenStream方法:- 用
flatMap处理每个条目,将递归产生的子流合并成一个大流 - 前缀拼接逻辑:避免顶层键出现多余的开头点号
- 子Map类型转换:通过
instanceof检查后安全转换,用注解消除编译器警告
- 用
- 测试输出:运行后会输出你预期的结果:
[map1.key1, value1] [map2.map3.key2, value2] [key3, value3]
这个实现既保留了递归处理嵌套的灵活性,又用上了Stream API的函数式风格,代码更简洁易读。
内容的提问来源于stack exchange,提问作者Nilesh Barai
相关产品推荐
相关产品推荐

