前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java树工具类,mysql树工具类

Java树工具类,mysql树工具类

作者头像
全栈程序员站长
发布2022-09-07 11:08:18
9560
发布2022-09-07 11:08:18
举报
文章被收录于专栏:全栈程序员必看

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

代码语言:javascript
复制
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;
    }


}

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档