且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何文件路径的列表转换为Java中的hireachial树

更新时间:2023-02-23 11:34:25

下面是一个非常简单的实现,这将给你从哪里开始的想法。 : - )

 进口java.io.PrintStream中;
进口java.util.Collections中;
进口的java.util.Map;
进口java.util.Scanner中;
进口java.util.TreeMap中;
进口java.util.regex.Pattern中;

公共类人呐{
    公共静态类节点{
        私人最终地图<字符串,节点>孩子=新TreeMap的<>();

        公共节点getChild(字符串名称){
            如果(children.containsKey(名))
                返回children.get(名称);
            节点结果=新节点();
            children.put(名称,结果);
            返回结果;
        }

        公共地图<字符串,节点>的getChildren(){
            返回Collections.unmodifiableMap(儿童);
        }
    }

    私人最终节点根=新节点();

    私有静态最终格局PATH_SEPARATOR = Pattern.compile(\\\\);
    公共无效让addpath(字符串路径){
        的String []名= PATH_SEPARATOR.split(路径);
        节点node =根;
        对于(字符串名称:名)
            节点= node.getChild(名称);
    }

    私有静态无效printHtml(节点的节点,为PrintStream出){
        地图<字符串,节点>儿童= node.getChildren();
        如果(children.isEmpty())
            返回;
        通过out.println(&其中; UL>中);
        对于(Map.Entry的<字符串,节点gt;儿童:children.entrySet()){
            的out.print(<李>);
            的out.print(child.getKey());
            printHtml(child.getValue(),出);
            通过out.println(< /李>);
        }
        通过out.println(&所述; / UL>中);
    }

    公共无效printHtml(PrintStream的出来){
        printHtml(根,出);
    }

    公共静态无效的主要(字串[] args){
        人呐自=新人呐();
        扫描仪扫描=新的扫描仪(System.in);
        而(scanner.hasNextLine())
            self.addPath(scanner.nextLine());
        self.printHtml(的System.out);
    }
}
 

本来,我想过做单独的类目录和普通文件,但是我觉得在这种情况下,因为所有你想要做的是打印的名称,在使用一个统一的节点类使得code简单有,这不仅是因为你可以避免实现访问者模式工作。

输出没有任何特定的很好的方式格式化。所以这件事情,你可以调整在code,如果你想要的;或者,您可以运行通过HTML Tidy的输出,如果你想要的东西更好看的。

我选择使用 TreeMap的,所以目录项字典顺序排序。如果你想使用的插入顺序而不是,只是改变使用的LinkedHashMap

can someone give me some pointers for this. I want take a list of file paths (just Strings) and convert into a hierachial tree like structure. So there are two tasks, parsing the strings to create a tree, and creating a tree or some sort of mapping structure to actually put the result into. (The third task is then to parse the tree to display as as a tree in html)

I'm using Java 7 so I assume i could use Paths to accomplish the first part, but struggling to get a clear algorithm in place.

C:\Music\Blur\Leisure
C:\Music\KateBush\WholeStory\Disc1
C:\Music\KateBush\WholeStory\Disc2
C:\Music\KateBush\The Kick Inside   
C:\Music\KateBush\The Dreaming
C:\MusicUnprocessed\Blue\ParkLife

So it gives

C:\
   Music
      Blur 
          Leisure
      Kate Bush
          Whole Story
               Disc 1
               Disc 2
          The Kick Inside
          The Dreaming
    MusicProcessing
      Blur
         ParkLife

Here's a very simple implementation, which will give you an idea of where to start. :-)

import java.io.PrintStream;
import java.util.Collections;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.regex.Pattern;

public class PathWalker {
    public static class Node {
        private final Map<String, Node> children = new TreeMap<>();

        public Node getChild(String name) {
            if (children.containsKey(name))
                return children.get(name);
            Node result = new Node();
            children.put(name, result);
            return result;
        }

        public Map<String, Node> getChildren() {
            return Collections.unmodifiableMap(children);
        }
    }

    private final Node root = new Node();

    private static final Pattern PATH_SEPARATOR = Pattern.compile("\\\\");
    public void addPath(String path) {
        String[] names = PATH_SEPARATOR.split(path);
        Node node = root;
        for (String name : names)
            node = node.getChild(name);
    }

    private static void printHtml(Node node, PrintStream out) {
        Map<String, Node> children = node.getChildren();
        if (children.isEmpty())
            return;
        out.println("<ul>");
        for (Map.Entry<String, Node> child : children.entrySet()) {
            out.print("<li>");
            out.print(child.getKey());
            printHtml(child.getValue(), out);
            out.println("</li>");
        }
        out.println("</ul>");
    }

    public void printHtml(PrintStream out) {
        printHtml(root, out);
    }

    public static void main(String[] args) {
        PathWalker self = new PathWalker();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine())
            self.addPath(scanner.nextLine());
        self.printHtml(System.out);
    }
}

Originally, I thought about making separate classes for directories and regular files, but I felt in this case that, since all you wanted to do is to print the names, that using a unified node class makes the code simpler to work with, not least because you can avoid having to implement the visitor pattern.

The output isn't formatted in any particular nice way. So that's something you can tweak the code on, if you want; alternatively, you can run the output through HTML Tidy if you want something nicer-looking.

I chose to use TreeMap, so the directory entries are lexicographically ordered. If you want to use insertion order instead, just change to use LinkedHashMap.