好久没写博文了,真是对不住啊,写博文真是一件快乐的事情啊
今天我想说的是一个常用的知识点,为什么要特别记录呢,,
因为这个非常非常之常用,,常用到什么程度呢,,
那就是几乎所有项目都会用到的方法,,也是为了避免重复造轮子,因此记录一下呗。。
今天要说的就是后端 组装树形结构数据 的方法,,比如部门多级下拉框,部门多级列表,菜单多级,地区多级等等,,
就是说只要你是树性的,那就都可以套用,这就是我说的车轮子,虽然这个车轮子并不那么优雅,高大上,,
以后会不断更新树形组装的方法的,如果大家有其他的好方法,,
欢迎评论区留言,一起打造更优雅的车轮子——树形数据组装
闲话不多说,进入正题。。
需求说明:
一个数据列表,要想分层级,比如一级,二级,三级...
就必须数据与数据之间一种层级关系,就好比下图,,
方式方法(一):
可以通过父子关系进行关联,即通过id和parentId来进行层级关联,,
(一级部门id就是二级部门的parentId,二级部门id就是三级部门的parentId,以此类推...... children是自己下一级的数据列表。)
这里不再啰嗦了,直接看代码,代码注释都加上了,也好理解。代码如下:
/**
* 树形数据列表返回实体
*/
@Data
public class TreeDeptVO {
@ApiModelProperty(value = "部门id")
private Long id;
@ApiModelProperty(value = "部门名称")
private String name;
@ApiModelProperty(value = "父级部门id")
private Long parentId;
@ApiModelProperty(value = "子级部门列表")
private List<TreeDeptVO> children;
}
@Service
public class DeptServiceImpl implements DeptService{
@Override
public List<TreeDeptVO> getDeptTreeList() {
List<TreeDeptVO> result = new ArrayList(); // 最终返回的数据
List<TreeDeptVO> list = []; // 未组装的所有数据(这里需要先查出所有数据列表(没有层级关系))
// 获取所有第一级的节点数据列表(这里我认定parentId==null的时候,就是第一级)
for (TreeDeptVO dept : list) {
if(null == dept.getParentId()) {
result.add(dept);
}
}
// 循环遍历第一级节点数据,,通过递归获取子节点
for (TreeDeptVO parent : result) {
assembleDeptTree(parent, list);
}
retrun result;
}
/**
* 组装树形数据(递归)
* @param parent 一级数据
* @param list 所有数据
* @return
*/
public static TreeDeptVO assembleDeptTree(TreeDeptVO parent, List<TreeDeptVO> list) {
for (TreeDeptVO dept : list) {
// 判断第一级的id == 子级的parentId
if(Objects.equals(parent.getId(),dept.getParentId())) {
dept = assembleDeptTree(dept, list);
// 此处是为了防止children为null时,下面add会报错
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<>());
}
parent.getChildren().add(dept);
}
}
return parent;
}
}
到这里,组装树形方法就告一段落了,感谢大家的不离不弃
大家有什么好的方法,欢迎大家来评论,相信这绝不是最好,最优雅的方法。