java 字符串路径集合转换成带有层次结构的JSON

本文介绍了一种将文件路径转换为树形JSON结构的方法,并提供了具体的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做业务遇到了一点麻烦,我调用某文件服务器的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: [] }
]

image

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

思路:
- 将字符串进行分类
- 构造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
     * <p>
     * 对于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;
    }
}

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值