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;
    }


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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 什么是多模态学习?

    什么是多模态学习?首先,什么叫做模态(Modality)呢?每一种信息的来源或者形式,都可以称为一种模态。例如,人有触觉,听觉,视觉,嗅觉;信息的媒介,有语音、视频、文字等;多种多样的传感器,如雷达、红外、加速度计等。以上的每一种都可以称为一种模态。同时,模态也可以有非常广泛的定义,比如我们可以把两种不同的语言当做是两种模态,甚至在两种不同情况下采集到的数据集,亦可认为是两种模态。因此,多模态机器学习,…

    2022年6月16日
  • 更新pip版本(anaconda更新pip)

    @更新pip版本#window:正常windows下更新pip版本的指令无法更新时,可以尝试如下指令python-mpipinstall–upgradepip#Ubuntu更新pip版本指令:sudo-Hpython-mpipinstall–upgradepip…

    2022年4月11日
  • ps去色的用法_索尼已经断气了.jpg

    ps去色的用法_索尼已经断气了.jpg原图1、ctrl+shift+u即去色2、ctrl+u降饱和度到最低3、图像——调整——渐变映射(前景色为黑色,背景色为白色或设置渐变为从黑到白)4、图像——调整——通道混合器勾选单色框5、图像——模式——灰度;再图像——模式——RGB6、图像——计算(调整好)——进入通道面板——复制Alpha1通道入图层7、进入通道面板——复制R、G、B任一效果最好的单色通道入图层8

    2022年10月5日
  • mysql系列:全网最全索引类型汇总「建议收藏」

    mysql系列:全网最全索引类型汇总「建议收藏」前言除了常见的普通索引,唯一索引,组合索引,大家还能说一下mysql中有哪些其他类型的索引吗?今天和大家一起总结mysql中有哪些索引类型。一、mysql中有哪些索引类型?聚簇索引(ClusteredIndex)非聚簇索引主键索引(PRIMARYKEY)辅助索引(SecondaryIndexes)HASH索引BTREE索引T-TREE索引R-Tree索引自适应hash索引(AdaptiveHashIndex)唯一索引(UNIQUEIndexs)普通索引(No

    2022年5月22日
  • boost之timer

    1.timer类实现2.重点说明2.1CLOCKS_PER_SECtimer的计数使用了标准头文件<ctime>里的clock()函数,它返回自进程启动以来的clock计数,每

    2021年12月28日
  • linux服务器路由添加命令_linux加静态路由命令

    linux服务器路由添加命令_linux加静态路由命令linux系统中添加路由的方法发布时间:2020-06-1711:38:59来源:亿速云阅读:95作者:Leah这篇文章将为大家详细讲解有关linux系统中添加路由的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一:使用route命令添加(临时路由)使用route命令添加的路由在机器重启或者网卡重启后路由就失效了,方法://添加到主机的路由#rou…

    2022年10月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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