Java扁平数据树型化

2021-04-01  本文已影响0人  大黑跟小白的日常
image.png

一个学生碰到的面试题,比较经典,企业使用率较高,这里做一下记录。

具体代码如下

// 业务展示层实体
class DepartmentVO extends Department {
    List<DepartmentVO> departmentVOList;
    public List<DepartmentVO> getDepartmentVOList() {
        return departmentVOList;
    }
    public void setDepartmentVOList(List<DepartmentVO> departmentVOList) {
        this.departmentVOList = departmentVOList;
    }
}
// 数据库实体
class Department {
    private Integer id;
    private String name;
    private Integer pid;
    public Department() {
    }
    public DepartmentVO parse2VO() {
        DepartmentVO departmentVO = new DepartmentVO();
        departmentVO.setName(this.name);
        departmentVO.setId(this.id);
        departmentVO.setPid(this.pid);
        return departmentVO;
    }
    public Department(Integer id, String name, Integer pid) {
        this.id = id;
        this.name = name;
        this.pid = pid;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
}

测试

    public static void main(String[] args) {
        //初始化测试数据
        List<Department> list = new ArrayList<>();
        list.add(new Department(100101, "后台开发部门", 1001));
        list.add(new Department(100102, "前台开发部门", 1001));
        list.add(new Department(100103, "测试部门", 1001));
        list.add(new Department(1001, "研发部", 10));
        list.add(new Department(1002, "财务部", 10));
        list.add(new Department(1003, "人事部", 10));
        list.add(new Department(10, "总裁办", null));
        // ...

        // 获取节点ID及其儿子们的map映射关系,方便后续使用
        HashMap<Integer, List<Department>> map = new HashMap<>();// 父节点id 及父节点下集合 map
        list.forEach(department -> {
            List<Department> departments = map.get(department.getPid());
            if (departments == null) {
                departments = new ArrayList<>();
                map.put(department.getPid(), departments);
            }
            departments.add(department);
        });

        List<Department> rootDepts = map.get(null);
        if(CollectionUtils.isEmpty(rootDepts) || rootDepts.size()>1){
            throw new RuntimeException("数据错误");
        }
        // 获取根节点
        Department department = rootDepts.get(0);
        DepartmentVO rootDept = department.parse2VO();
        // 获取完整根节点(含子项)
        DepartmentVO departmentVO = treeDeptList(rootDept, map);
        System.out.println(departmentVO);
    }

核心方法

     /**
      * @Author G_Y
      * @Description: 根据当前节点 递归获取其子节点并设置其中
      * @Date 2021/4/1 17:22
      * map:// 父节点id 及父节点下集合 的映射 map
      **/
    public static DepartmentVO treeDeptList(DepartmentVO departmentVO, Map<Integer, List<Department>> map) {
        Integer id = departmentVO.getId();// 当前节点id
        List<Department> sons = map.get(id);// 以当前节点id作为父节点的子节点集合
        if (sons == null) {
            // 如果不存在子节点,则不需要再操作
            return departmentVO;
        }
        // 如果存在则需要 将 字节点 加入到 当前节点的 departmentVOList 属性中
        ArrayList<DepartmentVO> departmentVOSList = new ArrayList<>();
        departmentVO.setDepartmentVOList(departmentVOSList);
        for (Department son : sons) {
            DepartmentVO sonVO = son.parse2VO();
            departmentVOSList.add(sonVO);
            // 使用递归 补全 sonVO节点下的 子集合 属性
            sonVO = treeDeptList(sonVO, map);
        }
        return departmentVO;
    }

结果演示


image.png

json转换结果展示:

{
    "id": 10,
    "name": "总裁办",
    "departmentVOList": [{
        "id": 1001,
        "name": "研发部",
        "pid": 10,
        "departmentVOList": [{
            "id": 100101,
            "name": "后台开发部门",
            "pid": 1001
        }, {
            "id": 100102,
            "name": "前台开发部门",
            "pid": 1001
        }, {
            "id": 100103,
            "name": "测试部门",
            "pid": 1001
        }]
    }, {
        "id": 1002,
        "name": "财务部",
        "pid": 10
    }, {
        "id": 1003,
        "name": "人事部",
        "pid": 10
    }]
}
上一篇下一篇

猜你喜欢

热点阅读