|
@@ -0,0 +1,142 @@
|
|
|
+package thyyxxk.webserver.utils;
|
|
|
+
|
|
|
+import cn.hutool.core.util.ReflectUtil;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
+
|
|
|
+public class TreeUtilV2<E> {
|
|
|
+
|
|
|
+ public interface TowFunction<T, T1> {
|
|
|
+ void apply(T t, T1 t1);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String id = "id";
|
|
|
+ private String parentId = "parentId";
|
|
|
+ private String children = "children";
|
|
|
+ private String sort = null;
|
|
|
+ private Function<E, Integer> sortFunction = null;
|
|
|
+ private TowFunction<E, E> towFunction = null;
|
|
|
+ private final List<E> data;
|
|
|
+
|
|
|
+ private static <T> T get(Object obj, String value, Object... args) {
|
|
|
+ return ReflectUtil.invoke(obj, StringUtil.getMethodName(value), args);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void set(Object obj, String value, Object... args) {
|
|
|
+ ReflectUtil.invoke(obj, StringUtil.setMethodName(value), args);
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2(List<E> list) {
|
|
|
+ this.data = list;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <E> TreeUtilV2<E> create(List<E> list) {
|
|
|
+ return new TreeUtilV2<>(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> id(String id) {
|
|
|
+ this.id = id;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> parentId(String parentId) {
|
|
|
+ this.parentId = parentId;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> children(String children) {
|
|
|
+ this.children = children;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> sort(String sort) {
|
|
|
+ this.sort = sort;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> sort(Function<E, Integer> sortFunction) {
|
|
|
+ this.sortFunction = sortFunction;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TreeUtilV2<E> fatherSonNode(TowFunction<E, E> towFunction) {
|
|
|
+ this.towFunction = towFunction;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<E> execute() {
|
|
|
+ return run();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addCallback(E parent, E item) {
|
|
|
+ if (towFunction == null) return;
|
|
|
+ towFunction.apply(parent, item);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<E> handelSort(List<E> resultList) {
|
|
|
+ if (sortFunction != null) {
|
|
|
+ return runSort(resultList, sortFunction);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtil.notBlank(sort)) {
|
|
|
+ return runSort(resultList, (a) -> get(a, sort));
|
|
|
+ }
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<E> runSort(List<E> resultList, Function<E, Integer> sortFunction) {
|
|
|
+ Stream<E> sorted = resultList
|
|
|
+ .stream()
|
|
|
+ .sorted((Comparator.comparing(a -> {
|
|
|
+ List<E> child = get(a, children);
|
|
|
+ if (child != null && !child.isEmpty()) {
|
|
|
+ set(a, children, runSort(child, sortFunction));
|
|
|
+ }
|
|
|
+ Integer sort = sortFunction.apply(a);
|
|
|
+ return sort == null ? 0 : sort;
|
|
|
+ }
|
|
|
+ )));
|
|
|
+ return sorted.collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<E> run() {
|
|
|
+ List<E> resultList = new ArrayList<>();
|
|
|
+ Map<Object, E> treeMap = new HashMap<>(data.size());
|
|
|
+
|
|
|
+ for (E item : data) {
|
|
|
+ Object key = get(item, id);
|
|
|
+ Object parent = get(item, parentId);
|
|
|
+ treeMap.put(key, item);
|
|
|
+ if (parent == null) {
|
|
|
+ addCallback(null, item);
|
|
|
+ resultList.add(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (E item : data) {
|
|
|
+ Object parentKey = get(item, parentId);
|
|
|
+ if (parentKey == null) continue;
|
|
|
+ E tree = treeMap.get(parentKey);
|
|
|
+ if (tree != null) {
|
|
|
+ List<E> child = get(tree, children);
|
|
|
+ if (child == null) {
|
|
|
+ set(tree, children, new ArrayList<>());
|
|
|
+ child = get(tree, children);
|
|
|
+ }
|
|
|
+ addCallback(tree, item);
|
|
|
+ child.add(item);
|
|
|
+ } else {
|
|
|
+ // 如果没有找到父节点就直接添加到主要的节点上
|
|
|
+ resultList.add(item);
|
|
|
+ addCallback(null, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return handelSort(resultList);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|