소스 검색

新增tree工具类

xiaochan 9 달 전
부모
커밋
7d49697e1e
1개의 변경된 파일142개의 추가작업 그리고 0개의 파일을 삭제
  1. 142 0
      src/main/java/thyyxxk/webserver/utils/TreeUtilV2.java

+ 142 - 0
src/main/java/thyyxxk/webserver/utils/TreeUtilV2.java

@@ -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);
+    }
+
+}
+