date
Mar 28, 2021
type
Post
status
Published
slug
dmzmx-tree
summary
概要:lambda表达式+递归实现树的返回,再也不需要嫌拼树麻烦了!
tags
代码实战
category
代码怎么写
password
Property
Sep 28, 2022 06:57 AM
icon
Tree
一、概述
1. 树结构数据
在大家平时的项目开发过程中,经常会遇到一些页面上要分类、分层展示的数据,或者以树的形式展示,如:
京东页面的分类标签
全国地市县下拉列表
电子卷宗目录树(网上看到这图片,怀旧的感觉呀,致曾经的电子卷宗团队)
2. 节点数据要素
树结构表基本字段设计,其中id和pId类型必须相同,也可以换成Long类型
字段名称 | 字段类型 | 含义 | 是否必须 |
id | String | 主键 | 是 |
name | String | 名称 | 是 |
order | int | 顺序 | 是 |
p_id | String | 父节点id | 是 |
3. 实现方式
- 后端返回保证保证层级顺序的list平铺数据,由前端组件遍历封装成Tree结构
- 后端直接返回Tree结构,前端根据树结构数据进行渲染
二、后端返回Tree结构数据
后端小伙伴们,有时候觉得拼装Tree很麻烦,尤其是前后端分离的项目,会选择跟前端小伙伴PK一下,推给前端做。其实更实用的方法还是后端返回Tree结果数据,前端直接用树组件解析渲染。
下面用非常简洁的几行代码,实现后端拼装Tree的过程,小伙伴们不需要再嫌弃拼树麻烦了~!
1. 示例基础类
@Data public class Directory { /** * 主键 */ private String id; /** * 名称 */ private String name; /** * 节点顺序 */ private int order; /** * 父节点id */ private String pId; /** * 子节点list(这个字段拼树结构专用) */ private List<Directory> children; }
2. 树的拼装逻辑
/** * 根据业务Id获取目录结构树 * * @param businessId 业务id * @return list */ public List<Directory> getDirectoryTree(String businessId) { //获取所有directory集合,来源可以是:1 数据库;2 json文件; List<Directory> directories = getAllDirectoriesByBusinessId(businessId); //lambda表达式流式计算 return directories.stream() //过滤器过滤出跟节点,directory.getPId() == null 是条件,按实际情况给条件就行 .filter(directory -> directory.getPId() == null) //拿出根目录,做children节点拼装,getDirectoryChildren 是一个递归函数,下边所有的层级都递归处理了 .peek(rootDirectory -> rootDirectory.setChildren(getDirectoryChildren(rootDirectory, directories))) //排序:按实际情况排 .sorted(Comparator.comparingInt(Directory::getOrder)) //最后转成list .collect(Collectors.toList()); } /** * 递归函数,组装children * * @param parentDirectory 父节点 * @param directories 全量集合 * @return children list */ private List<Directory> getDirectoryChildren(Directory parentDirectory, List<Directory> directories) { return directories.stream() //过滤出parentDirectory的所有子节点 .filter(directory -> directory.getPId().equals(parentDirectory.getId())) //递归setChildren .peek(directory -> directory.setChildren(getDirectoryChildren(directory, directories))) //排序 .sorted(Comparator.comparingInt(Directory::getOrder)) //转list .collect(Collectors.toList()); }
三、结语
怎么样,很简单吧!
Java8 引入的Lambda表达式+递归函数,简单紧凑的两行代码实现了Tree的数据拼装,并且还可以基于stream横向扩展,添加其他业务处理,所以好好学习下Lambda表达式吧!
下边提供一个学习Java Lambda表达式的网站: