在实际开发中经常会遇到返回树形结构的场景,特别是在处理文件系统或者是文件管理系统中。下面就介绍一下怎么将文件路径转成需要的树形结构。
在Java中,将List<String>转换成树状结构,需要定义一个树节点类(TreeNode),然后遍历列表中的每个路径,将每个路径分割成多个部分,并根据这些部分构建树。下面是一个简单的实现示例:
首先,定义一个树节点类TreeNode:
    public static class TreeNode {
        String val;
        Map<String, TreeNode> children;
        TreeNode(String val) {
            this.val = val;
            this.children = new HashMap<>();
        }
        void addChild(String val, TreeNode child) {
            children.put(val, child);
        }
        TreeNode getChild(String val) {
            return children.get(val);
        }
    } 
然后,可以使用以下封装的代码将List<String>转换成树状结构:
public static Map<String, TreeNode> buildTree(List<String> paths, String split) {
        logger.info("[字符串转Tree结构]开始...params paths:{}", paths);
        if (paths == null || paths.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<String, TreeNode> roots = new HashMap<>();
        for (String path : paths) {
            // 拆分路径
            String[] parts = path.split(split);
            if (parts.length == 0) {
                continue;
            }
            String rootVal = parts[0];
            TreeNode root = roots.get(rootVal);
            // 不存在,则创建它
            if (root == null) {
                root = new TreeNode(rootVal);
                roots.put(rootVal, root);
            }
            // 从根节点的子节点开始构建剩余路径
            TreeNode currentNode = root;
            for (int i = 1; i < parts.length; i++) {
                String part = parts[i];
                TreeNode child = currentNode.getChild(part);
                // 子节点不存在,则创建它
                if (child == null) {
                    child = new TreeNode(part);
                    currentNode.addChild(part, child);
                }
                // 移动到子节点,继续构建路径
                currentNode = child;
            }
        }
        return roots;
    } 
有时候我们需要将结果展示,这个时候就需要封装一个printTree方法,printTree方法使用一个prefix 参数来保持适当的缩进,从而清晰地显示树状结构。它首先打印当前节点的名称,然后递归地调用自身来打印每个子节点,每次递归调用时都增加缩进。
    public static void outTreeHtmlStyle(TreeNode root, String prefix, StringBuilder sb) {
        if (root == null) {
            return;
        }
        String emptyFlag = "  ";
        sb.append(emptyFlag).append(prefix).append(root.val).append("</br>");
        for (TreeNode child : root.children.values()) {
            outTreeHtmlStyle(child, prefix + "|" + emptyFlag, sb);
        }
    } 
最后在HTML中展示的效果如下:











