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

如何用SnakeYAML将点分隔键转为嵌套YAML对象?

问题描述

现有如下Java HashMap:

Map<String, Object> map = new HashMap<>();
map.put("a.b", "c");
map.put("a.d", "e");

使用SnakeYAML将其写入YAML文件的代码如下:

DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options);
String path = System.getProperty("user.dir") + "file.yaml";

try (FileWriter fileWriter = new FileWriter(path)) {
  yaml.dump(map, fileWriter);
} catch (IOException e) {
  throw new RuntimeException(e);
}

执行cat file.yaml后,文件内容为:

a.b: c
a.d: e

但期望将点分隔的键转换为嵌套对象,输出如下格式:

a:
  b: c
  d: e

调整DumperOptions的setIndent()或FlowStyle参数无法解决问题,请问如何通过SnakeYAML实现需求?是否需要更换实现方式?

解决方案

SnakeYAML本身不会自动将点分隔的键映射为嵌套对象,核心是需要先将扁平结构的Map转换为嵌套结构的Map,再进行序列化,无需更换实现方式。

1. 实现扁平Map转嵌套Map的工具方法

编写工具方法,递归处理带点分隔的键,将其拆分为嵌套的Map结构:

public static Map<String, Object> flattenToNestedMap(Map<String, Object> flatMap) {
    Map<String, Object> nestedMap = new HashMap<>();
    for (Map.Entry<String, Object> entry : flatMap.entrySet()) {
        String[] keys = entry.getKey().split("\\.", 2);
        if (keys.length == 1) {
            nestedMap.put(keys[0], entry.getValue());
        } else {
            Map<String, Object> childMap = (Map<String, Object>) nestedMap.computeIfAbsent(keys[0], k -> new HashMap<>());
            Map<String, Object> tempMap = new HashMap<>();
            tempMap.put(keys[1], entry.getValue());
            childMap.putAll(flattenToNestedMap(tempMap));
        }
    }
    return nestedMap;
}

2. 修改原代码,先转换再序列化

在dump之前,先调用上述方法将扁平Map转为嵌套结构:

DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options);
String path = System.getProperty("user.dir") + "file.yaml";

// 先转换为嵌套Map
Map<String, Object> nestedMap = flattenToNestedMap(map);

try (FileWriter fileWriter = new FileWriter(path)) {
    yaml.dump(nestedMap, fileWriter);
} catch (IOException e) {
    throw new RuntimeException(e);
}

3. 最终输出结果

执行后,file.yaml的内容将符合预期:

a:
  b: c
  d: e

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:08:37