概述

在实际开发中经常遇到需要查询树结构的需求。有两种方法,一种是递归查询子集,另一种是用Map映射子集。

递归

首先找到所有的一级主题,即没有父节点的类别。
然后通过stream.Map遍历处理每一个主题,
然后每一个一级主题都设置其子主题:
topicTree.setChildren(findChildren2(topicTree, topicTreeList))
findChildren2就是找到子主题的方法

@Override
public List<TopicTree> queryTopicTree2() {
     List<TopicTree> topicTreeList = this.list(Wrappers.<TopicTree>lambdaQuery().orderByDesc(TopicTree::getOrders));
     List<TopicTree> list = topicTreeList.stream()
             .filter(topicTree -> Objects.isNull(topicTree.getPid()))
             .map(topicTree -> {
                 topicTree.setChildren(findChildren2(topicTree, topicTreeList));
                 return topicTree;
             })
             .collect(Collectors.toList());
     return list;
 }

输入的参数有两个,一个是当前的主题opicTree,另一个是所有主题的列表。
找到子主题的关键在于,找到当前主题的id=子主题的pid。
过滤之后,用map处理每个子主题,而子主题的子主题则递归调用findChirdren2方法查找。

    private List<TopicTree> findChildren2(TopicTree topicTree, List<TopicTree> topicTreeList) {
        List<TopicTree> list = topicTreeList.stream()
                .filter(t -> Objects.nonNull(t.getPid()) && Objects.equals(t.getPid(), topicTree.getId()))
                .map(t -> {
                    t.setChildren(findChildren2(t, topicTreeList));
                    return t;
                })
                .collect(Collectors.toList());
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        return list;
    }

Map

首先找到所有的主题列表。
然后用groupingBy方法分组。
这种方式的关键点在于理解groupingBy方法。
Optional.ofNullable(t.getPid()))表示:
如果t.getPid()为null,则返回一个Option.Empty():List的键值对。
如果t.getPid()不为null,则返回Pid:List的键值对。
所以接下来遍历map中每一个键值,而值又是一个list,所以再遍历list,找到当前主题的id,然后在map中找pid=id的键值对,该键值对的值就是子主题。

@Override
    public List<TopicTree> queryTopicTree3() {
        List<TopicTree> topicTreeList = this.list(Wrappers.<TopicTree>lambdaQuery().orderByDesc(TopicTree::getOrders));
        Map<Optional<Long>, List<TopicTree>> topicTreeMap = topicTreeList.stream()
        .collect(Collectors.groupingBy(t -> Optional.ofNullable(t.getPid())));
        topicTreeMap.forEach((pid, topicTrees)->{
            topicTrees.forEach(topicTree -> {
                Long id = topicTree.getId();
                if(Objects.isNull(id)){
                    return;
                }
                List<TopicTree> children = topicTreeMap.get(Optional.of(id));
                if(!CollectionUtils.isEmpty(children)){
                    topicTree.setChildren(children);
                }
            });
        });
        List<TopicTree> res = topicTreeMap.get(Optional.empty());
        if(!CollectionUtils.isEmpty(res)){
            return res;
        }
        return res;
    }
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐