实现返回树状结构小记

需求需要接口返回树状结构并且支持检索。实现效果如图所示

返回DTO结构应该这样

java 复制代码
public class TreeDTO implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "编码")
    private String code;
 
    @ApiModelProperty(value = "子树列表")
    private List<TreeDTO> children;
  
  	public void updateChildren(List<CrtCategoryTreeDTO> children) {
        this.children = children;
    }
}

也曾咨询过大模型,感觉设计的比较复杂,实现困难。后面参考了同事的思路。在此基础上,增加了全路经的code来支持检索功能。

数据库对象设计

java 复制代码
@Data
public class TreeEntity{
  private String code;
  //直接上级节点编码
  private String parentCode;
  //记录该节点在树上的完整路径
  private List<String> fullPath
}
  • fullPath:记录该节点在树上的完整路径

构建树的思路

  • 首先把所有节点检索出来,这时候它们是平级的节点
  • 根据parentCode找出各个节点的子孙节点
  • 通过 递归 方式组装成树

查询所有节点

java 复制代码
private List<TreeDTO> searchNodeByName(String searchName) {

  
  	//查找所有树相关节点
    List<TreeEntity> allList = this.list(new LambdaQueryWrapper<TreeEntity>()
            .eq(TreeEntity::getDeleted, false));
  	//获取符合条件节点的全路径,这里是只要名称模糊匹配searchName即可
    Set<String> fullCode = buildFullCode(searchName, allList);
  	//根据全路径过滤出所有符合条件的节点
    List<TreeDTO> allTreeDTO = allList.stream()
            .filter(e -> fullCode.contains(e.getCode()))
            .map(Convertor::toTreeDTO)
            .toList();

    //组装成树
    return allTreeDTO.stream()
      			//找到种子节点也就是根节点作为启动节点
            .filter(each -> StrUtil.isBlank(each.getParentCode()))
      			//递归查找子孙节点
            .peek(rootDTO -> rootDTO.updateChildren(findChildren(rootDTO, allTreeDTO)))
            .toList();
}

查找子孙节点

java 复制代码
private List<TreeDTO> findChildren(TreeDTO parentDTO, List<TreeDTO> allDTO) {
    String parentCode = parentDTO.getCode();

    return allDTO.stream()
            .filter(dto -> Objects.equals(dto.getParentCode(), parentCode))
            //递归为子节点找孙子节点
            .peek(childDTO -> childDTO.updateChildren(findChildren(childDTO, allDTO)))
            .toList();
}

总结:

实现分类树说难也不难,说简单也不简单。关键是数据库实体必须有 直接上级节点编码(parentCode) 和 记录该节点在树上的完整路径(fullPath)

相关推荐
涉密IT资质笔记2 分钟前
涉密资质投入产出分析模型:时间成本、四块成本构成与 ROI 决策框架
java·开发语言·算法
木井巳5 分钟前
【BFS 解决拓扑排序】火星词典
java·算法·leetcode·广度优先·宽度优先·图搜索算法
霸道流氓气质5 分钟前
Java调用StableDiffusion/ComfyUI图像生成:DAG工作流编排、WebSocket实时进度与Flux模型集成的生产级实战
java·websocket·stable diffusion
北风toto16 分钟前
KMP 算法详解:从暴力匹配到 O(n+m) 的字符串搜索
java·开发语言·算法
weixin1997010801617 分钟前
《京东JOS API:落地方案、接口边界与业务踩坑 —— 联盟免费 vs 商家按量的双轨制》(附python源码)
java·网络·python
沫璃染墨18 分钟前
《从零入门数据结构与算法(二):线性表详解——从顺序表原理到静态与动态实现》
c语言·数据结构·顺序表
衡石科技19 分钟前
从语义准备到模型验收:HENGSHI SENSE Data Agent 的 RAG 与部署工程实践
java·大数据·人工智能·数据分析·rag
G018_star sky♬20 分钟前
java学习日记-多态与好玩的写法
java
撸串-研究生22 分钟前
面向景区的综合服务管理平台设计——以稻城亚丁景区为例【附源码】
java·开发语言·vue.js·前后端分离·稻城亚丁景区
爱读书的小胖23 分钟前
Codewars Sum of a Sequence Hard Core Version C 解题分析
c语言·数据结构·算法