通用节点树构建、通用树名称搜索

package cn.crservice.ic.bp.util;

import java.util.Comparator;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 树
 *
 * @author seliote
 * @since 2022-07-15
 */
public class TreeUtils {

    public static <T, I> List<T> build(List<T> list,
                                       Function<T, I> getId,
                                       Function<T, I> getParentId,
                                       Comparator<T> comparator,
                                       BiConsumer<T, List<T>> setSub) {
        var tree = rootList(list, getId, getParentId);
        sortList(tree, comparator);
        tree.forEach(n -> build(n, list, getId, getParentId, comparator, setSub));
        return tree;
    }

    private static <T, I> List<T> rootList(List<T> list,
                                           Function<T, I> getId,
                                           Function<T, I> getParentId) {
        var idSet = list.stream().map(getId).collect(Collectors.toSet());
        var parentIdSet = list.stream().map(getParentId).collect(Collectors.toSet());
        parentIdSet.removeAll(idSet);
        return list.stream().filter(i -> parentIdSet.contains(getParentId.apply(i))).collect(Collectors.toList());
    }

    private static <T> void sortList(List<T> list, Comparator<T> comparator) {
        list.sort(comparator);
    }

    private static <T, I> void build(T node,
                                     List<T> list,
                                     Function<T, I> getId,
                                     Function<T, I> getParentId,
                                     Comparator<T> comparator,
                                     BiConsumer<T, List<T>> setSub) {
        var id = getId.apply(node);
        var sub = list.stream().filter(i -> id.equals(getParentId.apply(i))).collect(Collectors.toList());
        if (sub.size() != 0) {
            sortList(sub, comparator);
            setSub.accept(node, sub);
            sub.forEach(s -> build(s, list, getId, getParentId, comparator, setSub));
        }
    }

    public static <T> void filterTreeByName(@NonNull List<T> tree,
                                            @NonNull Function<T, List<T>> getSub,
                                            @NonNull Function<T, String> getName,
                                            @NonNull String searchName,
                                            @NonNull Boolean reserveChild) {
        if (StringUtils.isEmpty(searchName)) {
            return;
        }
        for (Iterator<T> iterator = tree.iterator(); iterator.hasNext(); ) {
            T n = iterator.next();
            String name = getName.apply(n);
            if (reserveChild && !StringUtils.isEmpty(name) && name.contains(searchName)) {
                continue;
            }
            List<T> sub = getSub.apply(n);
            if (sub != null && sub.size() != 0) {
                filterTreeByName(sub, getSub, getName, searchName, reserveChild);
            }
            if ((sub == null || sub.size() == 0) && (StringUtils.isEmpty(name) || !name.contains(searchName))) {
                iterator.remove();
            }
        }
    }
}

用法

var tree = TreeUtils.build(list, Menu::getId, Menu::getParentId, Comparator.comparing(Menu::getOrderNo), Menu::setSub);
posted @ 2022-07-15 10:30  seliote  阅读(14)  评论(0)    收藏  举报