java树形结构工具包

该篇文章介绍了如何使用Java编程语言,通过函数和映射表,遍历数据列表并根据父ID和子ID关系构建树形结构,支持根据根节点标识选择性添加节点。
摘要由CSDN通过智能技术生成

/**
 * 遍历原始数据列表,按照给定的父ID获取函数对节点进行分组,构建一个以父ID为键、子节点列表为值的映射表。
 * 这样可以方便地根据节点的子ID快速找到其所有子节点。
 *
 * 初始化一个空的结果列表,用于存放最终形成的树形结构。
 *
 * 遍历原始数据列表中的每个节点:
 *   a. 使用子ID获取函数获取当前节点的子ID。
 *   b. 从映射表中查找与当前节点子ID对应的子节点列表。如果存在且非空,说明当前节点有子节点,
 *      则使用给定的子节点设置消费者将子节点列表赋给当前节点。
 *   c. 使用父ID获取函数获取当前节点的父ID。
 *   d. 根据传入的根节点标识判断当前节点是否应被加入结果列表:
 *      - 如果根节点标识为null,表示返回整个树形结构,因此将所有节点都加入结果列表;
 *      - 否则,只有当当前节点的父ID等于根节点标识时,才将当前节点加入结果列表。
 *
 * 最终返回构建好的树形结构列表。
 */

    /**
     * 将数据转换为树状数据
     * @param list               原始数据列表
     * @param rootTrait          根节点标识(如果为null,则返回所有节点组成的树)
     * @param parentValueGetter  获取节点父ID的函数
     * @param childValueGetter   获取节点子ID的函数
     * @param childSetter        设置节点子节点列表的消费者
     * @param <T>                节点类型
     * @param <R>                ID类型
     * @return                   树形数据
     */
    public static <T, R> List<T> buildTree(List<T> list, R rootTrait,
                                           Function<T, R> parentValueGetter,
                                           Function<T, R> childValueGetter,
                                           BiConsumer<T, List<T>> childSetter) {

        Map<R, List<T>> nodesByParentId = list.stream()
                .collect(Collectors.groupingBy(parentValueGetter));

        List<T> result = new ArrayList<>();
        for (T node : list) {
            R nodeId = childValueGetter.apply(node);
            List<T> children = nodesByParentId.get(nodeId);

            if (CollUtil.isNotEmpty(children)) {
                childSetter.accept(node, children);
            }

            R parentNodeId = parentValueGetter.apply(node);
            if (rootTrait == null || Objects.equals(parentNodeId, rootTrait)) {
                result.add(node);
            }
        }

        return result;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值