部门树形结构算法 — Java递归实现
将查询到的部门列表数据,进行父子节点树形结构排序
该功能适用需要树形结构的,不仅仅是部门树
步骤:
- 查询数据库,获得所有的部门列表
- 调用下面的实现方法
一、数据库结构如下:
CREATE TABLE `sm_school_department` (
`id` bigint(18) NOT NULL AUTO_INCREMENT BY GROUP,
`created_by` bigint(18) NOT NULL,
`created_date` datetime NOT NULL,
`last_updated_by` bigint(18) DEFAULT NULL,
`last_updated_date` datetime DEFAULT NULL,
`school_id` bigint(18) DEFAULT NULL COMMENT '驾校id',
`name` varchar(64) DEFAULT NULL COMMENT '部门名称',
`p_id` bigint(18) DEFAULT NULL COMMENT '上级部门',
`order_no` int(11) DEFAULT NULL COMMENT '排序号',
`contact` varchar(32) DEFAULT NULL COMMENT '联系人',
`telephone` varchar(32) DEFAULT NULL COMMENT '联系电话',
`status` char(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `Index_1` (`school_id`)
) ENGINE=InnoDB AUTO_INCREMENT=500002 DEFAULT CHARSET=utf8 COMMENT='部门信息' broadcast;
二、实体类如下:
package com.duolun.school.ddjd.business.humanmanage.bean.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class DepartmentVo {
@ApiModelProperty(value = "部门信息树")
private List<DepartmentVo> childDept = new ArrayList<>();
@ApiModelProperty(value = "部门id")
private Long id;
@ApiModelProperty(value = "部门名称")
private String name;
@ApiModelProperty(value = "上级部门")
private Long pId;
@ApiModelProperty(value = "排序号")
private Long orderNo;
@ApiModelProperty(value = "联系人")
private String contact;
@ApiModelProperty(value = "联系电话")
private String telephone;
}
三、实现方法代码:
/**
* 构建前端所需要树结构
*
* @param depts 部门列表
* @return 树结构列表
*/
public List<DepartmentVo> buildDeptTree(List<DepartmentVo> depts) {
List<DepartmentVo> deptList = new ArrayList<>();
List<Long> deptIdList = new ArrayList<>();
for (DepartmentVo dept : depts) {
deptIdList.add(dept.getId());
}
for (DepartmentVo dept : depts) {
// 如果是顶级节点,遍历该父节点所有子节点
if (!deptIdList.contains(dept.getPId())) {
recursionFn(depts, dept);
deptList.add(dept);
}
}
if (deptList.isEmpty()) {
deptList = depts;
}
return deptList;
}
/**
* 递归列表
* 结束条件为所遍历的节点无下一级节点
*
* @param list 查询获得的所有部门数据
* @param dept 顶级节点
*/
private void recursionFn(List<DepartmentVo> list, DepartmentVo dept) {
// 得到子节点列表
List<DepartmentVo> childList = getChildList(list, dept);
dept.setChildDept(childList);
for (DepartmentVo tChild : childList) {
// 如果子节点有下一级节点,得到下一级的节点列表
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 获得该节点的下一级子节点列表
*
* @param list 查询获得的所有部门数据
* @param dept 顶级节点
* @return 顶级节点的下一级子节点列表
*/
private List<DepartmentVo> getChildList(List<DepartmentVo> list, DepartmentVo dept) {
List<DepartmentVo> deptList = new ArrayList<>();
for (DepartmentVo d : list) {
// 遍历非顶级节点,并获得传入参数顶级节点的下一级子节点列表
if (d.getPId() != null && d.getPId().equals(dept.getId())) {
deptList.add(d);
}
}
return deptList;
}
/**
* 判断是否有子节点
*
* @param list 节点列表
* @param dept 部门节点
* @return Boolean
*/
private boolean hasChild(List<DepartmentVo> list, DepartmentVo dept) {
return getChildList(list, dept).size() > 0;
}
/**
* 调用方法,结果返回前端需要的树形结构数据
*
* @param department
* @return
*/
private List<DepartmentVo> getDepartmentList(DepartmentVo department, String schoolId) {
// 查询数据库中的部门数据
List<DepartmentVo> departments = smSchoolDepartmentService.getAllDepartManage(department, schoolId);
// 数据处理
return buildDeptTree(departments);
}