Java 通过使用递归函数实现树状结构

2023-03-28 09:49:19

项目中遇到一个接口,需要根据部门级别返回一个树状结构,包括部门,子部门,和部门下的员工,其结构如下:

{
	"code": 0,
	"data": [{
		"nodeId": 0,
		"label": "第一级部门",
		"choiced": 0,
		"children": [{
			"nodeId": 1,
			"label": "第二级部门",
			"choiced": 1,
			"children": [
                {
					"nodeId": 2,
					"label": "第三级部门",
					"choiced": 0,
					"children": []
				},
				{
					"nodeId": 3,
					"label": "第二级部门的人员",
					"choiced": 1
				}
			]
		}]
	}]
}

仔细分析一下,每一级的结构基本都相同,有"nodeId","label","choiced"这三个基本的信息,需要注意的是,部门有"children"字段,即子部门,而员工没有这个字段。


难点分析:

        这个结构的难点一个在于我们不知道这个部门的结构有几层,普通的循环无法实现这个功能,需要使用递归。另一个难点就是这个结构的children既有部门又有员工,但员工的数据结构与部门的结构又不太一样。

实现思路:

        使用递归的方式遍历部门列表数据,首先获得所有一级部门,然后在每个一级部门,去查找该部门下的二级部门和该部门下的员工......。最底层员工层我们可以写一个父类,然后部门去继承这个类并添一个children属性。

实现方法:

  父类NodeVo:

public class NodeVo {
    //省略get/set方法
    private Integer node_id;
    private String label;
    private Integer choiced;
}

子类AuthTreeVo:

public class AuthTreeVo extends NodeVo{
    //省略get/set方法
    private List<NodeVo> children;
}

 实现类AuthTree:

 构造方法:根据业务需求传参

public AuthTree(List<PersonWithDept> personList,List<PersonWithDept> personAuthList, List<Department> departmentList, List<Department> departmentAuthList){
        this.personList = personList;
        this.personAuthList = personAuthList;
        this.departmentList = departmentList;
        this.departmentAuthList = departmentAuthList;

    }

获取所有一级部门:getRootNode() 

public List<Department> getRootNode(){
        List<Department> departments = new ArrayList<>();
        for(Department department:departmentList){
            if(department.getParentId().equals(0)){
                departments.add(department);
            }
        }
        return departments;
    }

 实现树状结构的方法:makeTree()

public List<AuthTreeVo> makeTree(){
        List<AuthTreeVo> authTreeVos = new ArrayList<>();

        for(Department department:getRootNode()){
            AuthTreeVo authTreeVo = new AuthTreeVo();
            authTreeVo.setNode_id(department.getDepartmentId());
            authTreeVo.setLabel(department.getDepartmentName());

            authTreeVo=loopTree(department);
            authTreeVos.add(authTreeVo);
        }
        return authTreeVos;
    }

递归方法:loopTree()

public AuthTreeVo loopTree(Department department){
        AuthTreeVo authTreeVo = new AuthTreeVo();
        authTreeVo.setNode_id(department.getDepartmentId());
        authTreeVo.setLabel(department.getDepartmentName());
        authTreeVo.setChoiced(0);
        for(Department authDepartment: departmentAuthList) {
            if (authDepartment.getDepartmentId().equals(department.getDepartmentId())) {
                authTreeVo.setChoiced(1);
                break;
            }
        }

        List<NodeVo> authTreeVos = new ArrayList<>();

        for(Department departmentChild:departmentList){
            if(departmentChild.getParentId().equals(department.getDepartmentId())){
                authTreeVos.add(loopTree(departmentChild));
            }
        }

            for(PersonWithDept person: personList){
                if(person.getDepartmentId().equals(department.getDepartmentId())){
                    NodeVo nodeVo = new NodeVo();
                    nodeVo.setNode_id(person.getPersonId());
                    nodeVo.setLabel(person.getName());
                    nodeVo.setChoiced(0);
                    for(PersonWithDept authPerson:personAuthList){
                        if(authPerson.getPersonId().equals(person.getPersonId())){
                            nodeVo.setChoiced(1);
                            break;
                        }
                    }
                    authTreeVos.add(nodeVo);
                }
            }

        authTreeVo.setChildren(authTreeVos);
        return authTreeVo;
    }
  • 作者:萌奈加油努力
  • 原文链接:https://blog.csdn.net/s1ngle/article/details/126219171
    更新时间:2023-03-28 09:49:19