list集合转换为树型结构,并进行模糊搜索

VO主要结构

@Data
public class AmItemClassifyStandardTreeVO implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键GUID
     */
    private String guid;
    /**
     * 项目分类CODE
     */
    private String itemClassifyCode;
    /**
     * 项目父级分类CODE
     */
    private String parentItemClassifyCode;
    /**
     * 层级
     */
    private String level;
    /**
     * 子级
     */
    private List<AmItemClassifyStandardTreeVO> children;
}

将list集合转换为树型结构


public class Test{
    // 将数据库中查询出来的list集合传入此方法即可获得排成树形结构的list集合。
    public List<AmItemClassifyStandardTreeVO> createTree(List<AmItemClassifyStandardTreeVO> voList) {
   List<AmItemClassifyStandardTreeVO> treeVOS = voList.stream().filter(item -> StringUtils.equals((item.getParentItemClassifyCode()),"root"))
                .map(item -> {
                    item.setChildren(getChildren(item, voList));
                    return item;
                }).collect(Collectors.toList());
        return treeVOS;
    }
    
    /**
     * 循环调用遍历子级考勤类型
     * @param amItemClassifyStandardTreeVO
     * @param list
     * @return
     */
    private List<AmItemClassifyStandardTreeVO> getChildren(AmItemClassifyStandardTreeVO amItemClassifyStandardTreeVO,List<AmItemClassifyStandardTreeVO> list){
        List<AmItemClassifyStandardTreeVO> res = list.stream().filter(item -> StrUtil.equals(item.getParentItemClassifyCode(),amItemClassifyStandardTreeVO.getItemClassifyCode()))
                .map(item -> {
                    item.setChildren(getChildren(item, list));
                    return item;
                }).collect(Collectors.toList());
        return res;
    }

}

java树结构模糊查询

整体思路,查出数据库的数据,将集合转换为tree结构,即上面的方法,再对树进行模糊查询,具体代码如下:

/**
     * 分类树查询
     * @param itemClassifyName
     * @return
     */
    @Override
    public List<AmItemClassifyStandardTreeVO> getAttendanceItemTree(String itemClassifyName) {
        List<AmAdItemClassifyStandard> amAdItemClassifyStandardList = this.baseMapper.selectList(new LambdaQueryWrapper<>());
        List<AmItemClassifyStandardTreeVO> voList = BeanCopyUtils.copyList(amAdItemClassifyStandardList, AmItemClassifyStandardTreeVO.class);
        List<AmItemClassifyStandardTreeVO> treeVOS = voList.stream().filter(item -> StringUtils.equals((item.getParentItemClassifyCode()),"root"))
                .map(item -> {
                    item.setChildren(getChildren(item, voList));
                    return item;
                }).collect(Collectors.toList());
        if (StringUtils.isNotBlank(itemClassifyName)){
            //对树结构进行模糊查询
            this.filterTreeByKeyWord(treeVOS,itemClassifyName);
        }
        return treeVOS;
    }


    /**
     * 循环调用遍历子级考勤类型
     * @param amItemClassifyStandardTreeVO
     * @param list
     * @return
     */
    private List<AmItemClassifyStandardTreeVO> getChildren(AmItemClassifyStandardTreeVO amItemClassifyStandardTreeVO,List<AmItemClassifyStandardTreeVO> list){
        List<AmItemClassifyStandardTreeVO> res = list.stream().filter(item -> StrUtil.equals(item.getParentItemClassifyCode(),amItemClassifyStandardTreeVO.getItemClassifyCode()))
                .map(item -> {
                    item.setChildren(getChildren(item, list));
                    return item;
                }).collect(Collectors.toList());
        return res;
    }

    /**
     * 再通过树结构去模糊查询
     * @param data
     * @param itemClassifyName
     * @return
     */
    private List<AmItemClassifyStandardTreeVO> filterTreeByKeyWord(List<AmItemClassifyStandardTreeVO> data, String itemClassifyName) {

        if (!ListUtils.isNotEmpty(data)) {
            return data;
        }
        filterByName(data, itemClassifyName);
        return data;
    }

    /**
     * 递归方法
     * @param list 任意层级的节点
     * @param itemClassifyName 关键字
     */
    private void filterByName(List<AmItemClassifyStandardTreeVO> list, String itemClassifyName){
        Iterator<AmItemClassifyStandardTreeVO> parent = list.iterator();
        while (parent.hasNext()){
            //当前节点
            AmItemClassifyStandardTreeVO standardTreeVO = parent.next();
            if (StrUtil.isNotEmpty(itemClassifyName) && !standardTreeVO.getItemClassifyName().contains(itemClassifyName)) {
                //当前节点不包含关键字,继续遍历下一级
                // 取出下一级节点
                List<AmItemClassifyStandardTreeVO> children = standardTreeVO.getChildren();
                // 递归
                if (ListUtils.isNotEmpty(children)) {
                    filterByName(children, itemClassifyName);
                }
                //下一级节点都被移除了,那么父节点也移除,因为父节点也不包含关键字
                if (!ListUtils.isNotEmpty(standardTreeVO.getChildren())) {
                    parent.remove();
                }
            } else {
                //当前节点包含关键字,继续递归遍历
                //子节点递归如果不包含关键字则会进入if分支被删除
                List<AmItemClassifyStandardTreeVO> children = standardTreeVO.getChildren();
                // 递归
                if (ListUtils.isNotEmpty(children)) {
                    filterByName(children, itemClassifyName);
                }
            }
        }
    }

根据子节点查询所有父节点:

我们在实际开发过程中,可能会遇到根据子节点反查出父节点的需求,可以参考以下代码:

    /**
     * 根据字节点遍历出所有父节点
     * @param amAdItemClassifyStandard 子节点
     * @param allList 所有节点
     * @param parentList 根据子节点反查出的父节点及当前子节点
     */
    public void getParentItemClassify(AmAdItemClassifyStandard amAdItemClassifyStandard,List<AmAdItemClassifyStandard> allList,List<AmAdItemClassifyStandard> parentList) {
        // 查到root节点,结束方法,并保存到parentList集合中
        if (StringUtils.equals(amAdItemClassifyStandard.getParentItemClassifyCode(),"root")) {
            parentList.add(amAdItemClassifyStandard);
            return;
        }
        // 遍历所有数据中的数据,找到父节点
        AmAdItemClassifyStandard tblAmAdItemClassifyStandard = allList.stream().filter(
                e -> Objects.equals(e.getItemClassifyCode(), amAdItemClassifyStandard.getParentItemClassifyCode())
        ).findFirst().get();
        parentList.add(amAdItemClassifyStandard);
        // 递归调用
        this.getParentItemClassify(tblAmAdItemClassifyStandard,allList,parentList);
    }

再利用之前将集合转换为Tree结构的方法将parentList集合转换为树结构

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个基于树型结构的目录管理系统的实现代码,使用了Python语言。 ```python class Node: def __init__(self, name): self.name = name self.children = [] def add_child(self, child): self.children.append(child) def remove_child(self, child): self.children.remove(child) def get_children(self): return self.children def get_name(self): return self.name class FileSystem: def __init__(self): self.root = Node("root") def create_directory(self, path): current = self.root directories = path.split('/') for directory in directories: if directory not in [node.get_name() for node in current.get_children()]: current.add_child(Node(directory)) current = [node for node in current.get_children() if node.get_name() == directory][0] def remove_directory(self, path): current = self.root directories = path.split('/') for directory in directories: if directory in [node.get_name() for node in current.get_children()]: current = [node for node in current.get_children() if node.get_name() == directory][0] else: return False if current == self.root: return False else: current_parent = self.find_parent(self.root, current) current_parent.remove_child(current) def find_parent(self, node, child): if child in node.get_children(): return node else: for node in node.get_children(): result = self.find_parent(node, child) if result is not None: return result return None def list_directory(self, path): current = self.root directories = path.split('/') for directory in directories: if directory in [node.get_name() for node in current.get_children()]: current = [node for node in current.get_children() if node.get_name() == directory][0] else: return None return [node.get_name() for node in current.get_children()] ``` 上述代码实现了一个简单的目录管理系统,其中树的节点表示目录,节点之间通过子节点关系组成目录结构。`FileSystem`类包含了以下方法: - `create_directory(path)`:创建一个目录,需要传入目录路径。 - `remove_directory(path)`:删除一个目录,需要传入目录路径。 - `list_directory(path)`:列出一个目录下所有的子目录,需要传入目录路径。 其中,`Node`类为树节点,包含了节点名和子节点。`FileSystem`类为目录管理系统,包含了根节点和对树的操作方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值