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

如何从多维嵌套JSON数组中递归提取指定key的所有值

问题背景

使用Java处理多层嵌套的树形JSON结构时,初始实现仅遍历了最外层节点,仅能返回最外层的name字段值[Group],无法获取children字段下所有嵌套层级节点的目标字段值。

涉及的示例JSON结构如下:

[{"id":141741,"name":"Group","nodeTypeId":3,"deleted":false,"hasNodeAccesses":false,"children": [{"id":141742,"name":"Division","nodeTypeId":14,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141743,"name":"Site 1","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141746,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141744,"name":"Site 2","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141748,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141745,"name":"Site 3","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141750,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141752,"name":"ML1","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141755,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141753,"name":"ML2","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141756,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141754,"name":"ML3","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141757,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]}]}]}]

原有问题代码如下:

public List<String> getCapexStrategyNodeNames() {
        JsonNode capexStrategyNodeList = client.getCapexStrategyNodes();
        JSONArray nodes = capexStrategyNodeList.getArray();
        List<JSONObject> nodeList = nodes.toList();
        return retrieveValues(nodeList, "name");
    }

private List<String> retrieveValues(List<JSONObject> list, String key) {
    return list.stream()
            .map(val -> val.getString(key))
            .collect(Collectors.toList());
}

问题根因:原有retrieveValues方法只做了单层列表的流处理,没有递归遍历每个节点下挂载的children子节点数组,因此无法拿到深层节点的字段值。

实现方案

核心逻辑是通过深度优先递归遍历整棵树形结构:每处理一个节点时,先提取当前节点的目标字段值,再判断当前节点是否存在非空的children数组,若存在则递归处理所有子节点,将所有层级的目标值收集到同一个结果列表中。
修改后的可运行代码如下:

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public List<String> getCapexStrategyNodeNames() {
    JsonNode capexStrategyNodeList = client.getCapexStrategyNodes();
    JSONArray nodes = capexStrategyNodeList.getArray();
    List<JSONObject> rootNodeList = nodes.toJavaList(JSONObject.class);
    List<String> nameResult = new ArrayList<>();
    traverseAndCollect(rootNodeList, "name", nameResult);
    return nameResult;
}

/**
 * 递归遍历所有嵌套节点,收集指定key的字段值
 * @param currentLevelNodes 当前遍历层级的节点列表
 * @param targetKey 需要提取的字段名
 * @param collector 存储结果的列表
 */
private void traverseAndCollect(List<JSONObject> currentLevelNodes, String targetKey, List<String> collector) {
    for (JSONObject node : currentLevelNodes) {
        // 提取当前节点的目标字段,做非空判断避免空指针(示例中存在无name字段的节点)
        String currentValue = node.getString(targetKey);
        if (Objects.nonNull(currentValue)) {
            collector.add(currentValue);
        }
        // 获取当前节点的子节点数组
        JSONArray childArray = node.getJSONArray("children");
        if (Objects.nonNull(childArray) && !childArray.isEmpty()) {
            List<JSONObject> childNodes = childArray.toJavaList(JSONObject.class);
            // 递归处理子层级节点
            traverseAndCollect(childNodes, targetKey, collector);
        }
    }
}
结果说明

针对给出的示例JSON,代码运行后返回的结果为:

[Group, Division, Site 1, Converting, Site 2, Converting, Site 3, Converting, ML1, ML2, ML3]
适配提示
  • 上述代码基于FastJSON的API编写,如果使用Jackson、Gson等其他JSON处理库,仅需要替换节点取值、数组转List的对应API即可,递归遍历的核心逻辑无需改动
  • 如果树形结构的子节点字段名不是children,只需要修改代码中获取子数组的字段名即可复用逻辑
  • 非空判断逻辑可根据业务需求调整,如果业务要求所有节点必须携带目标字段,可以移除非空判断,改为字段缺失时抛出对应异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:27:35