最近做业务遇到了一点麻烦,我调用某文件服务器的API返回所有文件的路径大致是如下的字符串:

achievement/image/b97fa1c05ed1e34e02285f4b05ad227e.png
achievement/image/c162db7921d20ff35f0308af2c859c90.png
channel/image/9471461ad403aa40b1ae636fc6510815.png
channel/image/98a1778ba7d65546ecd67b59ef09acf9.png
/etc/init.d/mysql/mysql
/etc/profile
/tmp/垃圾.tmp
courses/pvpjson/402806c062c415c90162d74513f40077.json
courses/pvpjson/402806c062c415c90162d74513f4007s.json
......

我需要把这些数据以树的形式展示到页面上,以便加以操作

如何把他们转换成树结构的JSON字符串呢?

如何把它们以树的结构呈现在H5的页面中呢?

下面是layui官网tree 有关的数据结构 大致是这个样子的

https://fly.layui.com/jie/19038/

title: "节点1", value: "jd1", data: [ { title: "节点1.1", checked: true, disabled: true, value: "jd1.1", data: [] } , { title: "节点1.2", value: "jd1.2", checked: true, data: [] } , { title: "节点1.3", value: "jd1.3", disabled: true, data: [] } , { title: "节点1.4", value: "jd1.4", data: [] } title: "节点2", value: "jd2", data: [ { title: "节点2.1", value: "jd2.1", data: [] } , { title: "节点2.2", value: "jd2.2", data: [] } , { title: "节点2.3", value: "jd2.3", data: [] } , { title: "节点2.4", value: "jd2.4", data: [] } , { title: "节点3", value: "jd3", data: [] } , { title: "节点4", value: "jd4", data: [] }

想了很久虽然不是很完美,算法复杂度也比较高,但还是把我大致的过程写一下:

思路:
- 将字符串进行分类
- 构造Vo对象

针对这两点 我设计了 2个实体类

package pers.zpw.TreeTest;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
 * 对文件进行分类
 * Created by ZhuPengWei on 2018/8/17.
@Data
public class FileClassify {
     * composition/courses/2c918088615078af0161547c4a15006f.mp3
     * 对于composition   parent为null  self为composition   child为courses
     * 对于courses       parent为composition  self为courses   child为2c918088615078af0161547c4a15006f.mp3
     * 对于2c918088615078af0161547c4a15006f.mp3   parent为courses   self为2c918088615078af0161547c4a15006f.mp3   child为null
    /*父*/
    private String parent;
    /*自己*/
    private String self;
    /*子*/
    private String child;
    /*前缀*/
    private String prefix;
    public FileClassify(String parent, String self, String child, String prefix) {
        this.parent = parent;
        this.self = self;
        this.child = child;
        this.prefix = prefix;
package pers.zpw.TreeTest;
import lombok.Data;
import java.util.Date;
import java.util.List;
 * 文件树结构
 * Created by ZhuPengWei on 2018/8/17.
@Data
public class FileTreeVo {
    private String title;
    private List<FileTreeVo> data;
    @Override
    public String toString() {
        return "FileTreeVo{" +
                "title='" + title + '\'' +
                ", data=" + data +
                '}';

下面是完整的代码

package pers.zpw.TreeTest;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
 * 字符串路径转换成Tree格式
 * Created by ZhuPengWei on 2018/8/17.
public class StringPathToTree {
    private static List<String> urlList = new ArrayList<>();
    static {
        try {
            // url.txt存放 如最上面格式的字符串
            InputStream is = new FileInputStream(new File("url.txt"));
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    break;
                urlList.add(line);
        } catch (IOException e) {
            e.printStackTrace();
    public static void main(String[] args) {
        //文件分类后的集合
        List<FileClassify> fileClassifyList = new ArrayList<>();
        // 对数据进行分类
        for (String url : urlList) {
            String[] splitPath = url.split("/");
            for (int i = 0; i < splitPath.length; i++) {
                // 易得 parent,self,child 与i 的关系
                String parent = i == 0 ? null : splitPath[i - 1];
                String self = splitPath[i];
                String child = i + 1 == splitPath.length ? null : splitPath[i + 1];
                String prefix = parent == null ? "" : getPrefix(splitPath, i);
                fileClassifyList.add(new FileClassify(parent, self, child, prefix));
        // 筛选出parent 为null 的FileClassify集合
        // 根据FileClassify的getSelf 分组
        Map<String, List<FileClassify>> groupByMap = fileClassifyList.stream().filter(fileClassify -> fileClassify.getParent() == null).collect(Collectors.groupingBy(FileClassify::getSelf));
        // 此时  result 就是想要的结果
        List<FileTreeVo> result = getFileTreeVoList(groupByMap, fileClassifyList);
        System.out.println(result);
     * 获取文件前缀
     * 比如 image/12312/head.png
     * head.png的前缀为 image12312
     * @param splitPath 文件完整路径根据"/" 切割后的数组
     * @param endIndex  终止索引
     * @return 文件前缀
    private static String getPrefix(String[] splitPath, int endIndex) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < endIndex; i++) {
            result.append(splitPath[i]);
        return result.toString();
     * 获取文件Vo集合
     * @param root             根据self分组后的 文件分类结合
     * @param fileClassifyList 文件分类集合
    private static List<FileTreeVo> getFileTreeVoList(Map<String, List<FileClassify>> root, List<FileClassify> fileClassifyList) {
        List<FileTreeVo> result = new ArrayList<>();
        Set<Map.Entry<String, List<FileClassify>>> entries = root.entrySet();
        for (Map.Entry<String, List<FileClassify>> entry : entries) {
            FileTreeVo fileTreeVo = new FileTreeVo();
            String key = entry.getKey();
            fileTreeVo.setTitle(key);
            List<FileClassify> list = entry.getValue();
            for (FileClassify fileClassify : list) {
                if (StringUtils.isNotBlank(fileClassify.getChild())) {
                    // 首先筛选出 父节点 为key,前缀为父节点的前缀+本身 并且 子节点 不为空 的FileClassify集合
                    // 然后根据子节点 对集合进行分组
                    Map<String, List<FileClassify>> child = fileClassifyList.stream()
                            .filter(e -> key.equals(e.getParent()) && e.getPrefix().equals(fileClassify.getPrefix() + fileClassify.getSelf()) && StringUtils.isNoneBlank(e.getSelf()))
                            .collect(Collectors.groupingBy(FileClassify::getSelf));
                    fileTreeVo.setData(getFileTreeVoList(child, fileClassifyList));
            result.add(fileTreeVo);
        return result;

如果有更好的解决方案请私聊我,谢谢了

文章目录非递归二叉树的前序遍历 计蒜客 - 141非递归二叉树的中序遍历 计蒜客 - 144非递归二叉树的后序遍历 计蒜客 - 140二叉树中序遍历 51Nod - 2064求先序排列 洛谷 - P1030新二叉树 洛谷 - P1305 非递归二叉树的前序遍历 计蒜客 - 141 非递归二叉树的中序遍历 计蒜客 - 144 非递归二叉树的后序遍历 计蒜客 - 140 给定一个层数小于等于 10 的二叉树,输出对其遍历的节点名序列。 输入包括一行,为由空格分隔开的各节点,按照二叉树的分层遍历顺序给出 在实战开发中经常有需要处理树形菜单、树形目录等等等业务需求。而对于这种产品,在设计数据库时也建议使用idparentId的结构来做。但是最终前端显示多用hightChart或者Echart插件来实现。所以在给前端数据时,最好的做法就是把数据库结构话的数据处理成treeJson格式。第一步:引入fastjsoncom.alibabafastjson${fastjson.version}第二步:用到了... 以下面字符串为例(三种情况都有),初略搞了下&:(|(2):4,5,3708,3709),609,610,6042,612,7980,(|:845,839),535,7674,7979,11531import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;imp... #这个类是用于定义树的基本结构,leftjd:左节点,rightjd:右节点,data:数据 classTree(): def__init__(self,leftjd=0,rightjd=0,data=0): self.leftjd=leftjd self.rightjd=rightjd self.data... 算法学习(七)——排序总结 前几篇文章已经对一般的排序方法进行了介绍。 排序算法有很多,包括插入排序,冒泡排序,堆排序,归并排序,选择排序,计数排序,基数排序,桶排序,快速排序等。插入排序,堆排序,选择排序,归并排序和快速排序,冒泡排序都是比较排序,它们通过对数组中的元素进行比较来实现排序,其他排序算法则是利用非比较的其他方法来获得有关输入数组的排序信息。 下面就看一下,这些排序算法的时间空