Java树工具类,mysql树工具类

Java树工具类,mysql树工具类依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.0</version></dependency><dependency><groupI

大家好,又见面了,我是你们的朋友全栈君。

package com.ciih.workshop.utils;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.SneakyThrows;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 树形工具类-函数版
 *
 * @author sunziwen
 */

public class TreeUtil {


    /**
     * Map版本(速度比递归要快很多)
     * listToTree
     *
     * @param target      需转换的数据
     * @param getId       主键
     * @param getParentId 父id (父id必须和主键相同类型)
     * @param getChildren 子集
     * @param setChildren 子集
     * @return tree
     */
    public static <T, R> List<T> listToTree(List<T> target, Function<T, R> getId, Function<T, R> getParentId,
                                            Function<T, List<T>> getChildren, BiConsumer<T, List<T>> setChildren) {

        Map<R, T> oldMap = target.stream().collect(Collectors.toMap(getId, T -> T));
        List<T> result = new ArrayList<>();
        target.forEach(tree -> {
            T parent = oldMap.get(getParentId.apply(tree));
            if (parent == null) {
                result.add(tree);
            } else {
                List<T> ch = getChildren.apply(parent);
                if (ch == null) {
                    ch = new ArrayList<>();
                }
                ch.add(tree);
                setChildren.accept(parent, ch);
            }
        });
        return result;
    }

    /**
     * @param list          树结构的基础数据集
     * @param getIdFn       获取主键的函数
     * @param getParentIdFn 获取父节点的函数
     * @param getChildrenFn 获取子集的函数
     * @param <T>           t
     * @param <R>           r
     * @return t
     */
    @SneakyThrows
    public static <T, R> List<T> treeOut(List<T> list, Function<T, R> getIdFn, Function<T, R> getParentIdFn, SFunction<T, R> getChildrenFn) {
        /*所有元素的Id*/
        List<Object> ids = list.stream().map(getIdFn).collect(Collectors.toList());
        /*查出所有顶级节点*/
        List<T> topLevel = list.stream().filter(x -> {
            R apply = getParentIdFn.apply(x);
            return !ids.contains(apply);
        }).collect(Collectors.toList());
        return TreeUtil.recursion(topLevel, list, getIdFn, getParentIdFn, getChildrenFn);
    }


    @SneakyThrows
    private static <T, R> List<T> recursion(List<T> superLevel, List<T> list, Function<T, R> getIdFn, Function<T, R> getParentIdFn, SFunction<T, R> getChildrenFn) {
        //获取setChildren的Method
        Method writeReplaceMethod = getChildrenFn.getClass().getDeclaredMethod("writeReplace");
        boolean accessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(getChildrenFn);
        writeReplaceMethod.setAccessible(accessible);
        String setMethodName = serializedLambda.getImplMethodName().replaceFirst("g", "s");
        Method setMethod = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredMethod(setMethodName, List.class);

        for (T t : superLevel) {
            List<T> children = list.stream().filter(x -> {
                R apply = getParentIdFn.apply(x);
                R apply1 = getIdFn.apply(t);
                return apply.equals(apply1);
            }).collect(Collectors.toList());
            if (children.size() <= 0) {
                continue;
            }

            List<T> recursion = recursion(children, list, getIdFn, getParentIdFn, getChildrenFn);
            setMethod.invoke(t, recursion);
        }
        return superLevel;
    }


}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148050.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号