java 递归删除树节点

java 递归删除树节点,第1张

java 递归删除树节点

需求:按组织树和岗位树查询。(组织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=[])])]
 

 

    @Override
    public baseResponse getPostListByGradeId(Long gradeId) {
       baseResponse result = agencySvcClient.getPostListByAgencyIdList(gradeMemberRepository.findAgencyIdsByGradeId(gradeId));
        List agencyPostResponseList = result.getResult();
        if(CollectionUtils.isEmpty(agencyPostResponseList)) {
            return baseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }
        List userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
        Pageable pageable = PageUtil.getPageable(1, Constants.DEFAULT_MAX_PAGE_SIZE);
        Page userInfoPage = agcUsersEntityRepository.findPageByCondition(userIdList, null, null,
                null, null, pageable);
        if (Objects.isNull(userInfoPage) || CollectionUtils.isEmpty(userInfoPage.getContent())) {
            return baseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }

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

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

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

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

        return baseResponse.success(agencyPostResponseList);
    }

    
    @Override
    public baseResponse getOrganizationListByGradeId(Long gradeId) {
        List userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
        //批量查询用户组织(部门)信息
        List userOrganizationDTOList = agcUserOrganizationRepository.findByUserIdsOrAgencyId(userIdList, null);
        if(CollectionUtils.isEmpty(userOrganizationDTOList)){
            return baseResponse.failureEnum(HttpErrorCodes.NO_DATA);
        }
        //查询用户组织树
        Set orgIds = userOrganizationDTOList.stream().map(i -> i.getOrgId()).collect(Collectors.toSet());

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

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

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

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

    
    private void traverseOrgTree(List nodePathList, Long orgId, List 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());
            }
        }
    }

    
    private void markDelOrgNode(List nodePathList, List organizationList, List 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);
            }
        }
    }

    
    private void deleteOrgNode(OrganizationResponse invalidNode, List organizationList) {
        for(OrganizationResponse organizationResponse :organizationList){
            //找到父节点
            if(organizationResponse.getId().equals(invalidNode.getParentId())){
                List 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());
            }
        }
    }
    
    private List traverseOrgTree(Long orgId, List organizationList,
                                                       List 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;
    }

    
    private void markDelPostNode(List nodePathList, List postTreeResponseList, List 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);
            }
        }
    }

    
    private void deletePostNode(PostTreeResponse invalidNode, List 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 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());
            }
        }
    }

核心思路:

        ① 找到节点 

        ② 标记删除的节点

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

最终效果图:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5636670.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存