JAVA树结构在工作中用到的场景很多。但是程序猿就分两种:一种是可以看懂递归,一种是看不懂递归。这点很让我抓狂,自己有时候也记不住tree结构的写法。所以特地记录一下,以后工作中我要是遇到了,可以直接参考自己的掘金文章,毕竟年龄也大了,好记性不如烂笔头。
网上有很多转树形结构的工具,比如hutools的工具包等,这些我都不会考虑,本文只会手写组合树
1.部门表数据
如果要实现组合树结构,那么表设计必须要有 parent_id,如果需要支持排序,还需要提供order_num字段,这也是常用的树形结构表设计。其实还有可以设计的更完美一点,就是提供一个root_parent_id最顶层节点字段,这样在业务中,可以直接获取当前节点的根节点,就不需要一级一级往上回溯查找了,所以说表结构设计需要考虑扩展,这样是为什么表都是由公司的老手负责设计的原因。
2.组合树
基本的代码都贴了出来,就是mvc架构,没什么好说的,毕竟简单
实体类,注意子节点集合
@Data
@TableName("sys_dept")
public class DeptDo {
@TableId
private String deptId;
private String parentId;
private String deptName;
private Integer orderNum;
private String leader;
//用来放子结构的集合
@TableField(exist = false)
List<DeptDo> childrenList=new ArrayList<>();
}
service层
@Service
public class DeptService {
@Resource
private DeptMapper deptMapper;
public DeptDo tree() {
//查出所有数据
List<DeptDo> allDeptDoList = deptMapper.selectList(null);
//找到顶层节点
DeptDo rootDeptDo = allDeptDoList.stream().filter(d -> d.getParentId().equals("0")).collect(Collectors.toList()).get(0);
//递归+排序
combinationTree(rootDeptDo, allDeptDoList);
return rootDeptDo;
}
private void combinationTree(DeptDo root, List<DeptDo> allDeptDoList) {
for (DeptDo deptDo : allDeptDoList) {
//跳出递归的条件
if (deptDo.getParentId().equals(root.getDeptId())) {
//todo 业务代码
//递归调用
combinationTree(deptDo, allDeptDoList);
//组合树
root.getChildrenList().add(deptDo);
}
}
//根据某个字段排序
//reversed desc
//default asc
List<DeptDo> sortDeptDo = root.getChildrenList().stream().sorted(Comparator.comparingInt(DeptDo::getOrderNum)).collect(Collectors.toList());
root.setChildrenList(sortDeptDo);
}
}
3.总结
tree结构多少有点复杂,但是已经是一个很成熟的方案!所以,你可以参考我的文章,工作中遇到直接拿来魔改就可以了。其次,递归树的核心就是递归调用和跳出递归的条件,理清楚这两点就不算复杂,今天就这样了,👋再见了各位