java 递归删除树节点

14 篇文章 1 订阅
6 篇文章 0 订阅

需求:按组织树和岗位树查询。(组织org 和岗位都在机构下)

问题是:机构树查询出来的是全部的组织机构,需求是按人员所在机构,岗位展示树(把不在学员列表多余的组织和岗位节点删除):

 

 

上图可理解如下图: nodepath 会显示当前节点的所有父节点:nodePath=1785.1786.1787.1788

如标记的无效节点为:

2021-12-02 13:20:06.117  INFO 40468 --- [qtp335196473-36] c.g.b.m.service.impl.AgencyServiceImpl   : invalidPostList:[PostTreeResponse(id=1785, name=默认岗位组, title=默认岗位组, key=1785, level=1, postType=group, userNum=4, nodePath=1785, parentId=0, disabled=true, children=[PostTreeResponse(id=1786, name=默认岗位组, title=默认岗位组, key=1786, level=2, postType=group, userNum=4, nodePath=1785.1786, parentId=1785, disabled=true, children=[PostTreeResponse(id=1787, name=默认岗位组, title=默认岗位组, key=1787, level=3, postType=group, userNum=4, nodePath=1785.1786.1787, parentId=1786, disabled=true, children=[PostTreeResponse(id=1788, name=默认岗位, title=默认岗位, key=1788, level=4, postType=post, userNum=4, nodePath=1785.1786.1787.1788, parentId=1787, disabled=false, children=[])])])]), PostTreeResponse(id=1801, name=高顿机构, title=高顿机构, key=1801, level=1, postType=group, userNum=40, nodePath=1801, parentId=0, disabled=true, children=[PostTreeResponse(id=1802, name=高顿机构, title=高顿机构, key=1802, level=2, postType=post, userNum=40, nodePath=1801.1802, parentId=1801, disabled=false, children=[])]), PostTreeResponse(id=9502, name=哈哈哈, title=哈哈哈, key=9502, level=1, postType=group, userNum=2, nodePath=9502, parentId=0, disabled=true, children=[PostTreeResponse(id=9503, name=发发发, title=发发发, key=9503, level=2, postType=post, userNum=2, nodePath=9502.9503, parentId=9502, disabled=false, children=[])])]
 

 

/**
     * @Title: 根据班级id批量查询学员岗位
     * @Author: ken
     * @Description:
     * @Date: 2021/9/17  19:41
     * @Param: [gradeId]
     * @return com.gaodun.bcloud.mstat.response.BaseResponse<java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.AgencyPostResponse>>
     **/
    @Override
    public BaseResponse<List<AgencyPostResponse>> getPostListByGradeId(Long gradeId) {
       BaseResponse<List<AgencyPostResponse>> result = agencySvcClient.getPostListByAgencyIdList(gradeMemberRepository.findAgencyIdsByGradeId(gradeId));
        List<AgencyPostResponse> agencyPostResponseList = result.getResult();
        if(CollectionUtils.isEmpty(agencyPostResponseList)) {
            return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }
        List<Long> userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
        Pageable pageable = PageUtil.getPageable(1, Constants.DEFAULT_MAX_PAGE_SIZE);
        Page<BaseUserInfoDTO> userInfoPage = agcUsersEntityRepository.findPageByCondition(userIdList, null, null,
                null, null, pageable);
        if (Objects.isNull(userInfoPage) || CollectionUtils.isEmpty(userInfoPage.getContent())) {
            return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }

        List<BaseUserInfoDTO> content = userInfoPage.getContent();
        Set<Long> postIdSet = content.stream().map(BaseUserInfoDTO::getPostId).filter(Objects::nonNull).collect(Collectors.toSet());
        // 查找岗位节点
        List<AgcPostListEntity> postList = postListRepository.findAllAgcPostList(postIdSet);
        if(CollectionUtils.isEmpty(postList)){
            return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }

        List<String> nodePathList = postList.stream().map(AgcPostListEntity::getNodePath).collect(Collectors.toList());

        // 标记删除节点
        List<PostTreeResponse> invalidPostList = Lists.newArrayList();
        for (AgencyPostResponse agencyPostResponse : agencyPostResponseList) {
            List<PostTreeResponse> postTreeResponseList = agencyPostResponse.getPost();
            markDelPostNode(nodePathList, postTreeResponseList, invalidPostList);
        }
        log.info("invalidPostList:{}",invalidPostList.toString());

        // 删除节点
        for(PostTreeResponse invalidNode: invalidPostList) {
            for (AgencyPostResponse agencyPostResponse : agencyPostResponseList) {
                List<PostTreeResponse> postTreeResponseList = agencyPostResponse.getPost();
                deletePostNode(invalidNode, postTreeResponseList);
            }
        }
        agencyPostResponseList.removeIf(s -> CollectionUtils.isEmpty(s.getPost()));

        return BaseResponse.success(agencyPostResponseList);
    }

    /**
     * @Title: 根据机构id批量查询学员组织
     * @Author: ken
     * @Description: 遍历traverse
     * @Date: 2021/9/17  19:57
     * @Param: [gradeId]
     * @return com.gaodun.bcloud.mstat.response.BaseResponse<java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.AgencyOrganizationResponse>>
     **/
    @Override
    public BaseResponse<List<AgencyOrganizationResponse>> getOrganizationListByGradeId(Long gradeId) {
        List<Long> userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
        //批量查询用户组织(部门)信息
        List<UserOrganizationDTO> userOrganizationDTOList = agcUserOrganizationRepository.findByUserIdsOrAgencyId(userIdList, null);
        if(CollectionUtils.isEmpty(userOrganizationDTOList)){
            return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }
        //查询用户组织树
        Set<Long> orgIds = userOrganizationDTOList.stream().map(i -> i.getOrgId()).collect(Collectors.toSet());

        BaseResponse<List<AgencyOrganizationResponse>> result = agencySvcClient.getOrganizationListByAgencyIdList(gradeMemberRepository.findAgencyIdsByGradeId(gradeId));
        if(Objects.isNull(result) || CollectionUtils.isEmpty(result.getResult())){
            return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }

        List<AgencyOrganizationResponse> agencyOrganizationResponseList = result.getResult();
        // 查找学员组织节点
        List<String> nodePathList = Lists.newArrayList();
        for(Long orgId: orgIds) {
            for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
                List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
                traverseOrgTree(nodePathList, orgId, organizationList);
            }
        }

        // 标记删除节点
        List<OrganizationResponse> invalidNodeList = Lists.newArrayList();
        for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
            List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
            markDelOrgNode(nodePathList, organizationList, invalidNodeList);
        }
        //log.info("invalidNodeList:{}",invalidNodeList.toString());

        // 删除节点
        for(OrganizationResponse invalidNode: invalidNodeList) {
            for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
                List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
                deleteOrgNode(invalidNode, organizationList);
            }
        }
        //log.info("agencyOrganizationResponseList:{}",agencyOrganizationResponseList.toString());
        return BaseResponse.success(agencyOrganizationResponseList);
    }

    /**
     * @Title: 遍历树
     * @Author: ken
     * @Description:
     * @Date: 2021/12/2  10:35
     * @Param: [nodePathList, orgId, organizationList]
     * @return void
     **/
    private void traverseOrgTree(List<String> nodePathList, Long orgId, List<OrganizationResponse> organizationList) {
        for(OrganizationResponse organizationResponse :organizationList){
            if(organizationResponse.getNodePath().endsWith(String.valueOf(orgId))){
                nodePathList.add(organizationResponse.getNodePath());
                continue;
            }else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
                continue;
            }else{
                traverseOrgTree(nodePathList,orgId,organizationResponse.getChildren());
            }
        }
    }

    /**
     * @Title: 标记无效节点
     * @Author: ken
     * @Description:
     * @Date: 2021/12/2  10:34
     * @Param: [nodePathList, organizationList, invalidNodeList]
     * @return void
     **/
    private void markDelOrgNode(List<String> nodePathList, List<OrganizationResponse> organizationList, List<OrganizationResponse> invalidNodeList) {
        for(OrganizationResponse organizationResponse : organizationList){
            // 是否在路径标识
            boolean pathFlag = nodePathList .stream().anyMatch(x-> x.startsWith(organizationResponse.getNodePath()));
            if(!pathFlag){
                invalidNodeList.add(organizationResponse);
                continue;
            }else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
                continue;
            }else{
                markDelOrgNode(nodePathList,organizationResponse.getChildren(),invalidNodeList);
            }
        }
    }

    /**
     * @Title: 删除节点
     * @Author: ken
     * @Description:
     * @Date: 2021/12/2  10:34
     * @Param: [invalidNode, organizationList]
     * @return void
     **/
    private void deleteOrgNode(OrganizationResponse invalidNode, List<OrganizationResponse> organizationList) {
        for(OrganizationResponse organizationResponse :organizationList){
            //找到父节点
            if(organizationResponse.getId().equals(invalidNode.getParentId())){
                List<OrganizationResponse> childList = organizationResponse.getChildren();
                //移除无效节点
                childList.removeIf(s -> s.getId().equals(invalidNode.getId()));
                organizationResponse.setChildren(childList);
                continue;
            }else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
                continue;
            }else{
                deleteOrgNode(invalidNode, organizationResponse.getChildren());
            }
        }
    }
    /**
     * @Title: 遍历过滤组织(部门)树
     * @Author: ken
     * @Description:
     * @Date: 2021/12/1  11:12
     * @Param: [orgId, organizationList]
     * @return java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.OrganizationResponse>
     **/
    private List<OrganizationResponse> traverseOrgTree(Long orgId, List<OrganizationResponse> organizationList,
                                                       List<OrganizationResponse> organizationResponseLists) {
        for(OrganizationResponse organizationResponse : organizationList){
            if(orgId.equals(organizationResponse.getId())){
                organizationResponse.setChildren(null);
                organizationResponseLists.add(organizationResponse);
            }else if(!CollectionUtils.isEmpty(organizationResponse.getChildren())){
                traverseOrgTree(orgId, organizationResponse.getChildren(),organizationResponseLists);
            }else{
                log.info("@@ no node");
            }
        }
        return organizationResponseLists;
    }

    /**
     * @Title: 标记无效节点
     * @Author: ken
     * @Description:
     * @Date: 2021/12/2  13:18
     * @Param: [nodePathList, postTreeResponseList, invalidPostList]
     * @return void
     **/
    private void markDelPostNode(List<String> nodePathList, List<PostTreeResponse> postTreeResponseList, List<PostTreeResponse> invalidPostList) {
        for(PostTreeResponse postTreeResponse :postTreeResponseList){
            // 是否在路径标识
            boolean pathFlag = nodePathList .stream().anyMatch(x-> x.startsWith(postTreeResponse.getNodePath()));
            if(!pathFlag){
                invalidPostList.add(postTreeResponse);
                continue;
            }else if(CollectionUtils.isEmpty(postTreeResponse.getChildren())){
                continue;
            }else{
                markDelPostNode(nodePathList,postTreeResponse.getChildren(),invalidPostList);
            }
        }
    }

    /**
     * @Title: 删除无效节点
     * @Author: ken
     * @Description:
     * @Date: 2021/12/2  13:18
     * @Param: [invalidNode, postTreeResponseList]
     * @return void
     **/
    private void deletePostNode(PostTreeResponse invalidNode, List<PostTreeResponse> postTreeResponseList) {
        //对于没有父节点的 特殊处理
        postTreeResponseList.removeIf(s -> s.getParentId().equals(0L) && s.getNodePath().equals(invalidNode.getNodePath()));
        if(CollectionUtils.isEmpty(postTreeResponseList)){
            return;
        }
        for(PostTreeResponse postTreeResponse :postTreeResponseList){
            //对于没有父节点的
            postTreeResponseList.removeIf(s -> s.getParentId().equals(0L) && s.getNodePath().equals(invalidNode.getNodePath()));
            //找到父节点
            if(postTreeResponse.getId().equals(invalidNode.getParentId())){
                List<PostTreeResponse> childList = postTreeResponse.getChildren();
                //移除无效节点
                childList.removeIf(s -> s.getId().equals(invalidNode.getId()));
                postTreeResponse.setChildren(childList);
                continue;
            }else if(CollectionUtils.isEmpty(postTreeResponse.getChildren())){
                continue;
            }else{
                deletePostNode(invalidNode, postTreeResponse.getChildren());
            }
        }
    }

核心思路:

        ① 找到节点 

        ② 标记删除的节点

        ③ 删除节点。(切断当前节点跟父节点的联系,注意判断是否是父节点)

最终效果图:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值