You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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));
    }
}

代码细节解释

  1. flatWithStream方法:作为对外接口,调用递归流方法后,通过collect将流收集为HashMap,指定了初始化、累加和合并的逻辑。
  2. flattenStream方法:
    • 用flatMap处理每个条目,将递归产生的子流合并成一个大流
    • 前缀拼接逻辑:避免顶层键出现多余的开头点号
    • 子Map类型转换:通过instanceof检查后安全转换,用注解消除编译器警告
  3. 测试输出:运行后会输出你预期的结果:
    [map1.key1, value1]
    [map2.map3.key2, value2]
    [key3, value3]
    

这个实现既保留了递归处理嵌套的灵活性,又用上了Stream API的函数式风格,代码更简洁易读。

内容的提问来源于stack exchange,提问作者Nilesh Barai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:22:42