【问题标题】:Convert string paths directory structure into to JSON object with Java使用 Java 将字符串路径目录结构转换为 JSON 对象
【发布时间】:2021-11-29 19:57:51
【问题描述】:

我正在尝试在 Spring MVC 中使用自定义 Pojo Node 创建嵌套树视图, 在 exec command1="find $(pwd) -maxdepth 1 -type f -not -path '*/\\.*' | sort" 之后我从 JSch 库获得的输入将是一个字符串列表,其中包含当前工作目录下文件的绝对路径,如下例所示。

`List<String> paths = [
"/Sample Dir/sample.cpp",
"/Sample Dir/New Folder",
"/Sample Dir/New Folder/Sample.txt"];`

我需要使用以下模型创建分层 JSON 对象:

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

我正在尝试找出算法,如何将文件路径表示为提供以下 JSON 的 Node 类。 以下是我尝试过的代码,其中有一些我无法弄清楚的问题。

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

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

public class DemoMainClass {

    public static void main(String[] args) throws Exception{
        Node root = new Node("/");
        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(); 
        String jsonStr = Obj.writeValueAsString(root);
        System.out.println(jsonStr);
    }

    public static Node AddNode(String filePath, Node rootNode) {
        // convenience method. this creates the queue that we need for recursion from
        // the filepath for you
        if(filePath.startsWith("/")) {
            filePath = filePath.split("/",2)[1];
        }
        List<String> tokenList = Arrays.asList(filePath.split("/"));
        tokenList.remove(" ");
        // if you split a folder ending with / it leaves an empty string at the end and
        // we want to remove that
        if (StringUtils.isBlank(tokenList.get(tokenList.size() - 1))) {
            tokenList.remove(tokenList.size() - 1);
        }

        PriorityQueue<String> queue = new PriorityQueue<String>();
        queue.addAll(tokenList);
        return AddNode(queue, rootNode);
    }

    private static Node AddNode(Queue<String> tokens, Node rootNode) {
        // base case -> node wasnt found and tokens are gone :(
        if (tokens == null || tokens.isEmpty()) {
            return null;
        }

        // get current token, leaving only unsearched ones in the tokens object
        String current = tokens.remove();

        // create node if not already exists
        Node foundNode = rootNode.FindNode(current);
        if (foundNode != null) {
            // node exists! recurse
            return AddNode(tokens, foundNode);
        } else {
            // node doesnt exist! add it manually and recurse
            Node newNode = new Node(current);
            rootNode.getChildren().add(newNode);
            return AddNode(tokens, newNode);
        }
    }
}

class Node {
    public String name;
    public List<Node> children;
    public String location;
    
    public String getName() {
        return name;
    }

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

    public List<Node> getChildren() {
        return 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<Node>();
    }
    
    public Node(String fileName) {
        this.children = new ArrayList<Node>();
        this.name = fileName;
    }
    public Node FindNode(String data) {
        if (this.children == null || this.children.isEmpty()) {
            return null;
        }
        // check Node list to see if there are any that already exist
        return this.children.stream().filter(node -> node.getName().equalsIgnoreCase(data)).findFirst().orElse(null);
        // .FirstOrDefault(n => n.Data.equalIgnoreCase(data));
    }

}



    

下面是我得到的输出:

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

期望的输出如下,

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

你能帮我找出我错的地方吗?任何线索表示赞赏,在此先感谢。

【问题讨论】:

  • 具体是什么问题?
  • 问题是根据文件创建Node,还是根据Nodes制作json?
  • @DaveNewton 我不知道如何在将每个字符串拆分为“/”后递归地创建节点
  • @Ofek 我正在尝试找出算法,将 Stings 列表转换为 Node 类,但无法

标签: java json spring-mvc recursion


【解决方案1】:

您正在使用 PriorityQueue 它将按升序返回令牌,因为没有提供比较器。在优先级队列中,poll/remove 方法将首先删除最小的元素(取决于比较器)。相反,您应该使用 LinkedList 它将按照 FIFO 原则工作。 更新这个

PriorityQueue<String> queue = new PriorityQueue<String>();

到这里

Queue<String> queue = new LinkedList<>(tokenList);

这应该会为您提供所需的输出,但缺少逻辑的位置除外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 2014-07-30
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多