在实际开发中经常会遇到返回树形结构的场景,特别是在处理文件系统或者是文件管理系统中。下面就介绍一下怎么将文件路径转成需要的树形结构。
在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中展示的效果如下: