- 工具类:
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> 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;
}
}
- 使用示例:
public static void main(String[] args) {
//模拟数据
ArrayList<My> list = new ArrayList<My>() {{
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<My> result = TreeUtil.treeOut(list, My::getUserid, My::getPId, My::getChs);
//打印
System.out.println(JSON.toJSONString(result));
}
标签:Java,树结构,list,List,add,new,My,getIdFn
From: https://blog.51cto.com/u_14121041/6415447