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

如何用Streams API将嵌套HashMap转为指定格式JSON风格字符串

嵌套HashMap转自定义格式化字符串(无外部库实现)

需求场景

现有一个嵌套的Map<String, Object>结构:

Map<String, Object> m1 = new HashMap<>();
m1.put("name", "mary");
m1.put("email", "mary@email.com");
m1.put("address", new HashMap<>() {{
    put("firstLine", "101 Oracle");
    put("zipCode", "java 20");
}});

需要将其转换为以下格式的字符串(无外部依赖):

{
address : {
zipCode : Java 20,
firstLine : 101 Oracle
},
name : mary,
email : mary@mail.com
}

当前问题

现有代码仅能处理顶层Map,无法正确格式化嵌套的子Map:

String s = m1.entrySet().stream()
                .map(e -> e.getKey() + " : " + e.getValue())
                .collect(Collectors.joining(", " + "\n", "{" + "\n", "\n" + "}"));
System.out.println(s);

输出结果不符合预期,嵌套Map仍保留默认的toString()格式:

{
address : {zipCode=java 20, firstLine=101 Oracle}, 
name : mary, 
email : mary@email.com
}

解决方案:递归处理嵌套Map

核心思路是编写递归方法,判断每个值是否为Map类型:如果是则递归调用格式化逻辑,否则直接拼接值,同时处理换行和分隔符格式。

完整实现代码

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class MapFormatter {
    public static void main(String[] args) {
        Map<String, Object> m1 = new HashMap<>();
        m1.put("name", "mary");
        m1.put("email", "mary@email.com");
        m1.put("address", new HashMap<>() {{
            put("firstLine", "101 Oracle");
            put("zipCode", "java 20");
        }});

        String formatted = formatMap(m1);
        System.out.println(formatted);
    }

    private static String formatMap(Map<String, Object> map) {
        // 遍历所有entry,递归格式化值
        String entries = map.entrySet().stream()
                .map(entry -> {
                    String key = entry.getKey();
                    Object value = entry.getValue();
                    String valueStr;
                    if (value instanceof Map<?, ?>) {
                        // 递归处理嵌套的子Map
                        valueStr = formatMap((Map<String, Object>) value);
                    } else {
                        // 普通值直接转字符串,如需首字母大写可调用工具方法
                        valueStr = capitalizeFirstLetter(value.toString());
                    }
                    return key + " : " + valueStr;
                })
                .collect(Collectors.joining(",\n"));

        // 包裹外层大括号并添加换行
        return "{\n" + entries + "\n}";
    }

    // 工具方法:将字符串首字母大写(匹配示例中zipCode的输出格式)
    private static String capitalizeFirstLetter(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
}

输出结果

{
address : {
zipCode : Java 20,
firstLine : 101 Oracle
},
name : mary,
email : mary@email.com
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:46:05