如何高效的从部门树中添加人员列表形成人员部门(机构)树(不用递归listToTree)

前言

最近项目中有个查询展示人员部门树(所有人员和部门一次性加载)的需求,谨以此篇博客手把手给大家分享下。

需求

如何把人员信息(大概一万条)插入到部门(大概三千多条)树中?并以人员部门树结构展示?

思路

一开始我觉得总共也就一万三千多条数据怎么递归怎么查数据库(想当然)都是不怎么耗时的,
结果实现后接口查询居然需要十秒多,显然是不符合要求的。后来,我把数据先从数据库查出来然后对其操作,耗时一秒左右。废话不多说,看实现过程。

实现

SysOfficeTreeVO

private Long id;
private Long parentId;
private string name;
private string type;
private List<SysOfficeTreeVO> children;
  1. 把所有部门信息查询出来形成一个officeList
List<SysOffice> sysOfficeList = sysOfficeMapper.selectByCondition(condition);
  1. 将部门list转成树VO的list,并设置类型为部门(type为0)用来区分VO是人员还是部门
List<SysOfficeTreeVO> sysOfficeTreeVOList = BeanMapperUtil.mapList(sysOfficeList, SysOfficeTreeVO.class);
sysOfficeTreeVOList.forEach(v -> v.setType(DataConstant.ZERO_STR));
  1. 所有人员信息查询出来形成一个userList
List<SysUser> allUser = sysUserMapper.select(sysUser);
  1. 把用户对象当作一个部门对象,用户的部门id当作VO中的parentId,同时设置类型为人员type为1
List<SysOfficeTreeVO> user2Offices = changeUser2Office(allUser);
  1. 将两个list(部门,人员)传入方法listToTree转成树形结构
private List<SysOfficeTreeVO> listToTree4User(List<SysOfficeTreeVO> list, List<SysOfficeTreeVO> userList) {
    //根据treeUnique转成map
    Map<Integer, SysOfficeTreeVO> map = list.stream().collect(Collectors.toMap(SysOfficeTreeVO::getId, v -> v));
    //获取所有部门id
    List<Integer> ids = list.stream().map(SysOfficeTreeVO::getId).collect(Collectors.toList());
    List<SysOfficeTreeVO> tree = new ArrayList<>();
    SysOfficeTreeVO parentTreeNode;
    Integer pid;
    //把部门list和用户list合并
    list.addAll(userList);
    // 循环用户和部门合并后list
    for (SysOfficeTreeVO temp : list) {
        //获取当前部门或者用户的父级id
        pid = temp.getParentId();
        // 如果部门ids不包含当前对象的父级id,说明当前对象是顶级部门
        // 否则不是顶级部门也就是有父级部门,然后找到父级部门添加当前用户,
        if (!ids.contains(pid)) {
            tree.add(temp);
        } else {
            // 找到父级部门
            parentTreeNode = map.get(pid);
            if (parentTreeNode.getChildren() == null) {
                parentTreeNode.setChildren(new ArrayList<>());
            }
            // 添加当前用户(此时list中的数据也就变了)
            parentTreeNode.getChildren().add(temp);
        }
    }
    return tree;
}

另一个例子

@RestController
@RequestMapping("/sys/test")
public class Test extends BaseController {

    @GetMapping
    public ResponseEntity list() {
        List<SysOfficeTreeVO> list = Lists.newArrayList();
        SysOfficeTreeVO sysOfficeTreeVO = new SysOfficeTreeVO();
        sysOfficeTreeVO.setId(1);
        sysOfficeTreeVO.setName("江西省");
        sysOfficeTreeVO.setParentId(0);
        list.add(sysOfficeTreeVO);

        SysOfficeTreeVO sysOfficeTreeVO2 = new SysOfficeTreeVO();
        sysOfficeTreeVO2.setId(3);
        sysOfficeTreeVO2.setName("南昌市");
        sysOfficeTreeVO2.setParentId(1);
        list.add(sysOfficeTreeVO2);

        SysOfficeTreeVO sysOfficeTreeVO6 = new SysOfficeTreeVO();
        sysOfficeTreeVO6.setId(7);
        sysOfficeTreeVO6.setName("肇庆市");
        sysOfficeTreeVO6.setParentId(2);
        list.add(sysOfficeTreeVO6);

        SysOfficeTreeVO sysOfficeTreeVO3 = new SysOfficeTreeVO();
        sysOfficeTreeVO3.setId(4);
        sysOfficeTreeVO3.setName("上饶市");
        sysOfficeTreeVO3.setParentId(1);
        list.add(sysOfficeTreeVO3);

        SysOfficeTreeVO sysOfficeTreeVO4 = new SysOfficeTreeVO();
        sysOfficeTreeVO4.setId(5);
        sysOfficeTreeVO4.setName("广州市");
        sysOfficeTreeVO4.setParentId(2);
        list.add(sysOfficeTreeVO4);

        SysOfficeTreeVO sysOfficeTreeVO1 = new SysOfficeTreeVO();
        sysOfficeTreeVO1.setId(2);
        sysOfficeTreeVO1.setName("广东省");
        sysOfficeTreeVO1.setParentId(0);
        list.add(sysOfficeTreeVO1);

        SysOfficeTreeVO sysOfficeTreeVO5 = new SysOfficeTreeVO();
        sysOfficeTreeVO5.setId(6);
        sysOfficeTreeVO5.setName("深圳市");
        sysOfficeTreeVO5.setParentId(2);
        list.add(sysOfficeTreeVO5);


        List<SysOfficeTreeVO> listToTree = listToTree(list);
        return successResult(listToTree);
    }

    private List<SysOfficeTreeVO> listToTree(List<SysOfficeTreeVO> list) {
        Map<Integer, SysOfficeTreeVO> collect = list.stream().collect(Collectors.toMap(SysOfficeTreeVO::getId, v -> v));
        List<SysOfficeTreeVO> tree = Lists.newArrayList();
        Integer pid;
        SysOfficeTreeVO parrent;
        for (SysOfficeTreeVO sysOfficeTreeVO : list) {
            if (sysOfficeTreeVO.getParentId() == 0) {
                tree.add(sysOfficeTreeVO);
            } else {
                parrent = collect.get(sysOfficeTreeVO.getParentId());
                if (parrent.getChildren() == null) {
                    parrent.setChildren(new ArrayList<>());
                }
                parrent.getChildren().add(sysOfficeTreeVO);
            }
        }
        return tree;
    }
}

写在最后

非常感谢大家的认真阅读,如有不足,还望各位看官多批评指正=_=
技术交流秋秋群:719023986

微x关注:干饭必备外卖神券,每天领大额卷
微x关注:正好想买,自助查桃宝京d卷

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值