N个代码片段之递归实现

0,循环实现3层树结构

// 查询所有主包项目数据
Cwdemc_yx_lxsqPagination baseMain = new Cwdemc_yx_lxsqPagination();
baseMain.setXmlx("01");
List<Cwdemc_yx_lxsqTreeVO> mainProject = this.selectProjectData(baseMain);
// 查询所有内包项目数据
Cwdemc_yx_lxsqPagination baseInner = new Cwdemc_yx_lxsqPagination();
baseInner.setXmlx("02");
List<Cwdemc_yx_lxsqTreeVO> innerProject = this.selectProjectData(baseInner);
// 查询所有专包项目数据
Cwdemc_yx_lxsqPagination baseProf = new Cwdemc_yx_lxsqPagination();
baseProf.setXmlx("03");
List<Cwdemc_yx_lxsqTreeVO> profProject = this.selectProjectData(baseProf);
//查询所有数据组成主专内三层项目树,先定义主包项目集合
List<Cwdemc_yx_lxsqTreeVO> mainPackageList = new ArrayList();
//2,先把内包放进专包中,在把专包放进主包中,最后再把主包放进list中,返回的list即是树形结构了
if (mainProject.size()>0 && profProject.size()>0 && profProject.size()>0){
    mainProject.forEach(main ->{
        mainPackageList.add(main);
        List<Cwdemc_yx_lxsqTreeVO> profProjectList = new ArrayList<>();
        profProject.forEach(prof -> {
            if (prof.getSjxmid().equals(main.getXmid())){
                profProjectList.add(prof);
                main.setChildrenList(profProjectList);
                List<Cwdemc_yx_lxsqTreeVO> innerProjectList = new ArrayList<>();
                innerProject.forEach(inner -> {
                    innerProjectList.add(inner);
                    prof.setChildrenList(innerProjectList);
                });
            }
        });
    });
}

1, 典型递归构建树型列表

案例一
public List<Cwdemc_yx_lxsqEntity> getProjectListByXmid(String xmid) {
    QueryWrapper<Cwdemc_yx_lxsqEntity> queryWrapper = new QueryWrapper<>();
    UserInfo userInfo = userProvider.get();
    // 默认查询条件:默认查询当前所在机构(orgid=)审批通过(flowstatus=2)并且未删除(delete!=1)的数据
    queryWrapper.lambda()
            .eq(Cwdemc_yx_lxsqEntity::getOrgid, userInfo.getOrganizeId())
            .eq(Cwdemc_yx_lxsqEntity::getFlowstatus, FlowTaskStatusEnum.Adopt.getCode())
            .ne(Cwdemc_yx_lxsqEntity::getDel, 1)
            .eq(Cwdemc_yx_lxsqEntity::getChangeStatus, Constants.CHANGE_STATUS_NORMAL)
            .isNotNull(Cwdemc_yx_lxsqEntity::getSjxmid);
    List<Cwdemc_yx_lxsqEntity> list = this.list(queryWrapper);
    List<Cwdemc_yx_lxsqEntity> sonList = new ArrayList<>();

    findSon(xmid, list, sonList);

    return sonList;
}
private void findSon(String sjxmid, List<Cwdemc_yx_lxsqEntity> allList, List<Cwdemc_yx_lxsqEntity> sonList) {

    allList.forEach(son -> {
        if (son.getSjxmid().equals(sjxmid)) {
            sonList.add(son);
            findSon(son.getXmid(), allList, sonList);
        }
    });
}

@ApiOperation("根据公司id获取下级公司及下级部门所有数据")
@GetMapping("/TreeById/{id}")
public ActionResult<ListVO<OrganizeTreeVO>> TreeById(@PathVariable("id") String id) {
    // 查询选中机构
    OrganizeEntity org = organizeService.getById(id);
    //准备树结构VO
    OrganizeTreeVO parent =  new OrganizeTreeVO();
    //把entity对象转为准备好的树结构对象
    BeanUtils.copyProperties(org,parent);
    //查询所有组织
    List<OrganizeEntity> allList = organizeService.getList();
    // 过滤无效数据
    Iterator<OrganizeEntity> iterator = allList.iterator();
    while (iterator.hasNext()) {
        OrganizeEntity organizeEntity = iterator.next();
        if (organizeEntity.getEnabledMark() != 1) {
            iterator.remove();
        }
        if (organizeEntity.getDeleteMark() != null){
            iterator.remove();
        }
    }
    //把所有组织entity对象转为VO树结构对象
    List<OrganizeTreeVO> allListVO = JsonUtil.getJsonToList(allList, OrganizeTreeVO.class);
    // 遍历集合
    allListVO.forEach(node->{
        //找到所有数据中,我们要的顶级id
        if(node.getId().equals(parent.getId())){
            //找到顶级,开始递归找自己(需要两个容器:1,带children属性和顶级数据的树形对象。2,带所有数据的树形对象)
            this.buildTree(parent,allListVO);
        }
    });
    return ActionResult.success(parent);
}
//构建树的私有方法
private void buildTree(OrganizeTreeVO parent,List<OrganizeTreeVO> allListVO){
    //实例化children对象
    List<OrganizeTreeVO> children = new ArrayList<>();
    //循环遍历传过来的所有数据
    allListVO.forEach(node->{
         //逐条,拿parentId,对比
        if(node.getParentId().equals(parent.getId())){
            //如果拿到的parentId等于顶级id,则拿到子数据,进入if
            //将子数据加入进children对象中
            children.add(node);
            //每条数据都有可能有子数据,调用自己,把自己当做parent
            buildTree(node,allListVO);
        }
    });
    parent.setChildren(children);
}

2, 构建有层级编号的树结构

@Override
public List<ComfortEventTypesVO> getTreeList(ComfortEventTypesQuery query) {
    if (StringUtils.isBlank(query.getTypeName())) {
        // 直接查询全部未删除节点构建完整树
        List<ComfortEventTypes> allNodes = baseMapper.selectList(
                Wrappers.lambdaQuery(ComfortEventTypes.class)
                        .eq(ComfortEventTypes::getIsDelete, DELETE_0)
        );
        List<ComfortEventTypesVO> tree = buildTree(allNodes, "0", 1);
        populateCreatorNames(tree);
        return tree;
    }

    // 模糊查询符合条件的节点(可能是子节点)
    LambdaQueryWrapper<ComfortEventTypes> wrapper = Wrappers.lambdaQuery(ComfortEventTypes.class)
            .eq(ComfortEventTypes::getIsDelete, DELETE_0)
            .like(StringUtils.isNotBlank(query.getTypeName()), ComfortEventTypes::getTypeName, query.getTypeName());
    List<ComfortEventTypes> matchedNodes = baseMapper.selectList(wrapper);

    if (matchedNodes.isEmpty()) {
        return Collections.emptyList();
    }

    // 收集所有父节点ID(通过解析 pids 字段)
    Set<String> parentIds = new HashSet<>();
    for (ComfortEventTypes node : matchedNodes) {
        if (StringUtils.isNotBlank(node.getPids())) {
            Collections.addAll(parentIds, node.getPids().split(","));
        }
    }

    // 获取已匹配节点的ID集合
    Set<String> matchedNodeIds = matchedNodes.stream()
            .map(ComfortEventTypes::getId)
            .collect(Collectors.toSet());

    // 查询所有父节点(排除已匹配的节点)
    List<ComfortEventTypes> parentNodes = baseMapper.selectList(
            Wrappers.lambdaQuery(ComfortEventTypes.class)
                    .in(ComfortEventTypes::getId, parentIds)
                    .eq(ComfortEventTypes::getIsDelete, DELETE_0)
                    .notIn(!matchedNodeIds.isEmpty(), ComfortEventTypes::getId, matchedNodeIds)
    );

    // 使用Map进行ID去重合并
    Map<String, ComfortEventTypes> nodeMap = new LinkedHashMap<>();
    matchedNodes.forEach(node -> nodeMap.put(node.getId(), node));
    parentNodes.forEach(node -> nodeMap.putIfAbsent(node.getId(), node));

    // 构建完整树形结构
    List<ComfortEventTypesVO> tree = buildTree(new ArrayList<>(nodeMap.values()), "0", 1);
    populateCreatorNames(tree);
    return tree;
}

@Override
public Page<ComfortEventTypesVO> pageList(ComfortEventTypesPage query) {
    return baseMapper.selectVoPage(Querys.page(query.getPageModel()), Querys.wrapper(query, ComfortEventTypes.class));
}

// 递归构建树形结构
private List<ComfortEventTypesVO> buildTree(List<ComfortEventTypes> nodes, String parentId, Integer level) {
    return nodes.stream()
            .filter(node -> parentId.equals(node.getParentId()))
            .sorted(Comparator.comparing(ComfortEventTypes::getCreateTime).reversed())
            .map(node -> {
                ComfortEventTypesVO vo = convertToVO(node);
                vo.setChildren(buildTree(nodes, node.getId(), level + 1));
                vo.setLevel(level);
                return vo;
            }).collect(Collectors.toList());
}

// 实体转 VO
private ComfortEventTypesVO convertToVO(ComfortEventTypes entity) {
    ComfortEventTypesVO vo = new ComfortEventTypesVO();
    vo.setId(entity.getId());
    vo.setTypeName(entity.getTypeName());
    vo.setParentId(entity.getParentId());
    vo.setPids(entity.getPids());
    vo.setCreateTime(entity.getCreateTime());
    vo.setCreateBy(entity.getCreateBy());
    return vo;
}

用map纵横定位的方式实现树结构

Map<String,Cwdemc_yx_lxsqTreeVO> map = new HashMap();
List<Cwdemc_yx_lxsqTreeVO> mainPackageList = new ArrayList<>();
List<Cwdemc_yx_lxsqTreeVO> allProject = this.selectProjectData(cwdemc_yx_lxsqPagination);
allProject.forEach(all -> {
    map.put(all.getXmid(),all);
});

allProject.forEach(project -> {
    String pid = project.getSjxmid();
    if (StringUtil.isNotEmpty(pid)) {
        Cwdemc_yx_lxsqTreeVO o = map.get(pid);
        if(Objects.nonNull(o)){
            //上级对象的子级加入当前对象
            o.getChildrenList().add(project);
        }else{
            if(StringUtil.isBlank(pid)){
                //把当前对象加入定义好的list
                mainPackageList.add(project);
            }
        }
    } else {
        mainPackageList.add(project);
    }
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值