java构建tree,并且带搜索

需求

构建tree,要求查询节点关键字时要携带所有直属上级节点。

思路

1.先查询全部节点数据,过滤出带关键字的节点数据。然后通过过滤出来的节点进行递归查找直属上级,最后根据结果构建tree
2.先查询所有节点,构建成tree,然后通过递归对tree过滤出带关键字的节点

代码

这里针对第2种思路进行实现

controller

@ApiOperation(value = "根据项目名称搜索tree")
@GetMapping("/searchTree")
public R<List<AppraiseItemTreeVo>> searchTree(String projectName) {
    return R.ok(iAppraiseItemService.treeList(projectName));
}

IService

/**
 * 根据项目名称获取tree,查询子集关键字时要携带所有直属上级结构
 *
 * @param projectName
 * @return
 */
List<AppraiseItemTreeVo> treeList(String projectName);

ServiceImpl

/**
 * 根据项目名称获取tree,查询子集关键字时要携带所有上级结构
 *
 * @param projectName
 * @return
 */
@Override
public List<AppraiseItemTreeVo> treeList(String projectName) {
    // 查询所有节点
    LambdaQueryWrapper<AppraiseItem> queryWrapper = new LambdaQueryWrapper<>();
    List<AppraiseItem> appraiseItemList = baseMapper.selectList(queryWrapper);
    // 查询所有父节点
    queryWrapper.eq(AppraiseItem::getParentId, 0);
    List<AppraiseItem> parentList = baseMapper.selectList(queryWrapper);
    List<AppraiseItemTreeVo> result = new ArrayList<>();
    if (CollectionUtils.isEmpty(parentList)) {
        return result;
    }
    // 先构建树
    parentList.forEach(item -> result.add(buildChildren(item, appraiseItemList)));
    // 关键字检索
    return doSearch(result, projectName);
}

/**
 * 构建树状结构
 *
 * @param item
 * @param list
 * @return
 */
private AppraiseItemTreeVo buildChildren(AppraiseItem item, List<AppraiseItem> list) {
    List<AppraiseItemTreeVo> children = new ArrayList<>();
    for (AppraiseItem appraiseItem : list) {
        if (Objects.equals(item.getId(), appraiseItem.getParentId())) {
            children.add(buildChildren(appraiseItem, list));
        }
    }
    AppraiseItemTreeVo vo = new AppraiseItemTreeVo();
    vo.setId(String.valueOf(item.getId()));
    vo.setParentId(String.valueOf(item.getParentId()));
    vo.setUnit(item.getUnit());
    vo.setOrderBy(item.getOrderBy());
    vo.setProjectName(item.getProjectName());
    vo.setIsHasSon(item.getIsHasSon());
    // 对子集合排序,排序字段为null的排在第一位
    children = children.stream().sorted(Comparator.comparing(AppraiseItemTreeVo::getOrderBy, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    vo.setChildren(children);
    return vo;
}


/**
 * tree 关键字搜索
 *
 * @param searchList
 * @param keyWord
 * @return
 */
private List<AppraiseItemTreeVo> doSearch(List<AppraiseItemTreeVo> searchList, String keyWord) {
    List<AppraiseItemTreeVo> resultList = new ArrayList<>();
    for (AppraiseItemTreeVo treeVo : searchList) {
        // 判断是否包括keyWord
        String projectName = treeVo.getProjectName();
        if (projectName.contains(keyWord)) {
            // 如果存在关键字继续递归子集
            treeVo.setChildren(doSearch(treeVo.getChildren(), keyWord));
            resultList.add(treeVo);
        } else {
            // 继续递归
            List<AppraiseItemTreeVo> children = doSearch(treeVo.getChildren(), keyWord);
            if (!CollectionUtils.isEmpty(children)) {
                // 把子节点列表加到节点上
                treeVo.setChildren(children);
                resultList.add(treeVo);
            }
        }
    }
    // 对最外层排序,排序字段为null的排在第一位
    resultList = resultList.stream().sorted(Comparator.comparing(AppraiseItemTreeVo::getOrderBy, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    return resultList;
}

mapper 和 vo就不展示了

如图效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值