Java集合List转树结构工具类-函数版

  • 工具类:
package com.example.mindsa.util.tree;

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

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

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

public class TreeUtil {
    /**
     * @param list          树结构的基础数据集
     * @param getIdFn       获取主键的函数
     * @param getParentIdFn 获取父节点的函数
     * @param getChildrenFn 获取子集的函数
     * @param            t
     * @param            r
     * @return t
     */
    @SneakyThrows
    public static  List treeOut(List list, Function getIdFn, Function getParentIdFn, SFunction getChildrenFn) {
        /*所有元素的Id*/
        List ids = list.stream().map(getIdFn).collect(Collectors.toList());
        /*查出所有顶级节点*/
        List 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  List recursion(List superLevel, List list, Function getIdFn, Function getParentIdFn, SFunction 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 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 recursion = recursion(children, list, getIdFn, getParentIdFn, getChildrenFn);
            setMethod.invoke(t, recursion);
        }
        return superLevel;
    }


}

 

  • 使用示例:
public static void main(String[] args) {
        //模拟数据
        ArrayList list = new ArrayList() {
    {
            add(new My("1", "-1", "a"));
            add(new My("2", "-1", "aa"));
            add(new My("3", "1", "b"));
            add(new My("4", "1", "c"));
            add(new My("5", "3", "d"));
            add(new My("6", "5", "e"));
            add(new My("7", "6", "f"));
            add(new My("8", "2", "g"));
            add(new My("9", "8", "h"));
            add(new My("10", "9", "i"));
        }};

        //使用工具类:
        List result = TreeUtil.treeOut(list, My::getUserid, My::getPId, My::getChs);
        //打印
        System.out.println(JSON.toJSONString(result));
    }
  • 大功告成了,如果有问题请加博主V:sunziwen3366

你可能感兴趣的:(Java专栏,java,spring)