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

Java如何将绝对路径列表转换为自定义Node类层级JSON结构

问题修复方案

核心问题清单

  • 错误使用PriorityQueue存储路径层级token:优先级队列会按自然排序输出元素,完全打乱路径原有层级顺序,是结构异常的核心原因
  • Arrays.asList返回固定长度列表,调用remove方法会抛出UnsupportedOperationException,原有删除逻辑本身存在运行异常
  • 空格删除逻辑错误:路径中Sample Dir这类带空格的目录名是合法名称,直接删除空格会导致名称匹配失败
  • 未对location字段赋值,导致输出该字段全为null
  • 最终序列化根节点对象本身,而非根节点下的第一层子节点数组,和预期输出结构不符

修正后代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;

public class DemoMainClass {

    public static void main(String[] args) throws Exception{
        Node root = new Node("/");
        root.setLocation(""); // 根节点location设为空,方便子节点拼接
        AddNode("/Sample Dir/sample.cpp", root);
        AddNode("/Sample Dir/New Folder", root);
        AddNode("/Sample Dir/New Folder/Sample.txt", root);
        AddNode("/Sample Dir/New Folder/demo.txt", root);
        ObjectMapper Obj = new ObjectMapper();
        // 配置序列化时忽略null值,匹配你期望的输出格式
        Obj.setSerializationInclusion(Inclusion.NON_NULL);
        // 序列化根节点的子节点数组,而非根节点本身
        String jsonStr = Obj.writerWithDefaultPrettyPrinter().writeValueAsString(root.getChildren());
        System.out.println(jsonStr);
    }

    public static Node AddNode(String filePath, Node rootNode) {
        if(filePath.startsWith("/")) {
            filePath = filePath.split("/",2)[1];
        }
        // 转成可变长度的ArrayList
        List<String> tokenList = new ArrayList<>(Arrays.asList(filePath.split("/")));
        // 仅处理末尾空串(路径末尾带/的情况)
        if (tokenList.size() > 0 && StringUtils.isBlank(tokenList.get(tokenList.size() - 1))) {
            tokenList.remove(tokenList.size() - 1);
        }
        // 用LinkedList保证插入顺序,不要用PriorityQueue
        Queue<String> queue = new LinkedList<>();
        queue.addAll(tokenList);
        return AddNode(queue, rootNode);
    }

    private static Node AddNode(Queue<String> tokens, Node parentNode) {
        if (tokens == null || tokens.isEmpty()) {
            return null;
        }
        String current = tokens.remove();
        Node foundNode = parentNode.FindNode(current);
        if (foundNode != null) {
            return AddNode(tokens, foundNode);
        } else {
            Node newNode = new Node(current);
            // 拼接location:父节点location + / + 当前节点名,父节点是根的话直接用当前节点名
            String location = StringUtils.isBlank(parentNode.getLocation()) ? current : parentNode.getLocation() + "/" + current;
            newNode.setLocation(location);
            parentNode.getChildren().add(newNode);
            return AddNode(tokens, newNode);
        }
    }
}

class Node {
    private String name;
    private List<Node> children;
    private String location;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 空children返回null,匹配你期望的输出格式
    public List<Node> getChildren() {
        return children == null || children.isEmpty() ? null : children;
    }

    public void setChildren(List<Node> children) {
        this.children = children;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public Node() {
        this.children = new ArrayList<>();
    }

    public Node(String fileName) {
        this.children = new ArrayList<>();
        this.name = fileName;
    }
    public Node FindNode(String data) {
        if (this.children == null || this.children.isEmpty()) {
            return null;
        }
        // 如果系统目录大小写敏感,可将equalsIgnoreCase改为equals
        return this.children.stream().filter(node -> node.getName().equalsIgnoreCase(data)).findFirst().orElse(null);
    }
}

输出结果

[ {
  "name" : "Sample Dir",
  "children" : [ {
    "name" : "sample.cpp",
    "location" : "Sample Dir/sample.cpp"
  }, {
    "name" : "New Folder",
    "children" : [ {
      "name" : "Sample.txt",
      "location" : "Sample Dir/New Folder/Sample.txt"
    }, {
      "name" : "demo.txt",
      "location" : "Sample Dir/New Folder/demo.txt"
    } ],
    "location" : "Sample Dir/New Folder"
  } ],
  "location" : "Sample Dir"
} ]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:57:02