java实现的树形结构工具类TreeUtil



import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author xiaozhongyu
 * @description 树形结构工具
 * @createTime 2023年09月19日 15:57:00
 */
public class TreeUtil {

    public abstract static class ITree<ID> {

        /**
         * id
         */
        protected ID id;

        /**
         * 父Id
         */
        protected ID parentId;

        /**
         * 排序字段(默认从小到大排序)
         */
        protected Integer sort = 0;

        /**
         * 所有的子集列表
         */
        protected List<ITree<ID>> children;

        public ID getId() {
            return id;
        }

        public void setId(ID id) {
            this.id = id;
        }

        public ID getParentId() {
            return parentId;
        }

        public void setParentId(ID parentId) {
            this.parentId = parentId;
        }

        public Integer getSort() {
            return sort;
        }

        public void setSort(Integer sort) {
            this.sort = sort;
        }

        public List<ITree<ID>> getChildren() {
            return children;
        }

        public void setChildren(List<ITree<ID>> children) {
            this.children = children;
        }

        public ITree(ID id, ID parentId, Integer sort, List<ITree<ID>> children) {
            this.id = id;
            this.parentId = parentId;
            this.sort = sort;
            this.children = children;
        }

        public ITree() {
        }

        /**
         * 是否是顶层
         * @return boolean
         */
        protected abstract boolean firstLevel();
    }


    /**
     *
     * 生成树形结构
     * @param list list集合需要继承ITree
     * @return {@link List}<{@link T}>
     */
    public static <ID, T extends ITree<ID>> List<T> generateTree(List<T> list) {
        Objects.requireNonNull(list, "参数不能为空");
        //根据parentId分组
        Map<ID, List<ITree<ID>>> map = list.stream()
                .filter(item -> !item.firstLevel())
                .collect(Collectors.groupingBy(ITree::getParentId));
        //给每一项设置子集,并排序
        list.forEach(item -> {
            List<ITree<ID>> children = map.get(item.getId());
            if (Objects.nonNull(children)) {
                item.setChildren(
                        children.stream()
                                .sorted(Comparator.comparing(ITree::getSort))
                                .collect(Collectors.toList())
                );
            }
        });
        //过滤出所有的一级菜单,并排序
        return list.stream()
                .filter(ITree::firstLevel)
                .sorted(Comparator.comparing(ITree::getSort))
                .collect(Collectors.toList());
    }
}

下面是如何使用它:



import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;


public class Demo3 {

    private static List<Menu> getMenuList() {
        List<Menu> list = new ArrayList<>();
        list.add(new Menu(1, "系统设置", 0, 10));
        list.add(new Menu(2, "日志管理", 0, 30));
        list.add(new Menu(3, "关于我们", 0, 20));
        list.add(new Menu(4, "员工管理", 1, 8));
        list.add(new Menu(5, "角色管理", 1, 10));
        list.add(new Menu(6, "菜单管理", 1, 2));
        list.add(new Menu(7, "系统日志管理", 2, 8));
        list.add(new Menu(8, "登录日志管理", 2, 1));
        list.add(new Menu(9, "操作日志管理", 7, 10));
        return list;
    }

    public static void main(String[] args) {
        List<Menu> menuList = TreeUtil.generateTree(getMenuList());
        System.out.println(JSON.toJSONString(menuList));
    }
}

附上Menu类:




public class Menu extends TreeUtil.ITree<Integer> {

    private String name;

    public Menu(Integer id, String name, Integer parentId, Integer sort) {
        super(id, parentId, sort, null);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean firstLevel() {
        return getParentId() == 0;
    }
}