美文网首页Java进阶之路
java 树状结构数据的对象封装

java 树状结构数据的对象封装

作者: 东本三月 | 来源:发表于2020-09-14 11:10 被阅读0次

    场景

    树状结构的菜单数据,封装好提供给前端.
    核心方法:mergeList()
    前置条件:节点具有层级信息

    
    import lombok.Data;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    @Data
    public class MenuNode implements Comparable, Serializable {
    
        /**
         * 节点id
         */
        private Long id;
    
        /**
         * 父节点
         */
        private Long parentId;
    
        /**
         * 节点名称
         */
        private String name;
    
        /**
         * 节点层级
         */
        private Integer level;
    
        /**
         * 菜单的类型 1 系统 2菜单 3 按钮
         */
        private Integer type;
    
        /**
         * 节点的排序
         */
        private Integer num;
    
        /**
         * 节点的url
         */
        private String url;
    
        /**
         * 节点图标
         */
        private String icon;
    
        /**
         * 子节点的集合
         */
        private List<MenuNode> children;
    
        /**
         * 查询子节点时候的临时集合
         */
        private List<MenuNode> linkedList = new ArrayList<>();
    
        public MenuNode() {
            super();
        }
    
        public MenuNode(Long id, Long parentId) {
            super();
            this.id = id;
            this.parentId = parentId;
        }
    
        /**
         * 重写排序比较接口,首先根据等级排序,然后更具排序字段排序
         *
         * @param o
         * @return
         */
        @Override
        public int compareTo(Object o) {
            MenuNode menuNode = (MenuNode) o;
            Integer num = menuNode.getNum();
            Integer levels = menuNode.getLevel();
            if (num == null) {
                num = 0;
            }
            if (levels == null) {
                levels = 0;
            }
            if (this.level.compareTo(levels) == 0) {
                return this.num.compareTo(num);
            } else {
                return this.level.compareTo(levels);
            }
    
        }
    
        /**
         * 构建页面菜单列表
         */
        public static List<MenuNode> buildTitle(List<MenuNode> nodes) {
            if (nodes.size() <= 0) {
                return nodes;
            }
    
            //剔除非菜单
            nodes.removeIf(node -> !node.getType().equals(BaseIntegerEnum.MENU_TYPE_IS_MENU.getValue()));
    
            //对菜单排序,返回列表按菜单等级,序号的排序方式排列
            Collections.sort(nodes);
            return mergeList(nodes, nodes.get(nodes.size() - 1).getLevel(), null);
        }
    
        /**
         * 递归合并数组为子数组,最后返回第一层
         *
         * @param menuList
         * @param listMap
         * @return
         */
        private static List<MenuNode> mergeList(List<MenuNode> menuList, int rank, Map<Long, List<MenuNode>> listMap) {
            //保存当次调用总共合并了多少元素
            int n;
            //保存当次调用总共合并出来的list
            Map<Long, List<MenuNode>> currentMap = new HashMap<>();
            //由于按等级从小到大排序,需要从后往前排序
            //判断该节点是否属于当前循环的等级,不等于则跳出循环
            for (n = menuList.size() - 1; n >= 0 && menuList.get(n).getLevel() == rank; n--) {
                //判断之前的调用是否有返回以该节点的id为key的map,有则设置为children列表。
                if (listMap != null && listMap.get(menuList.get(n).getId()) != null) {
                    menuList.get(n).setChildren(listMap.get(menuList.get(n).getId()));
                }
                if (menuList.get(n).getParentId() != null && menuList.get(n).getParentId() != 0) {
                    //判断当前节点所属的pid是否已经创建了以该pid为key的键值对,没有则创建新的链表
                    currentMap.computeIfAbsent(menuList.get(n).getParentId(), k -> new LinkedList<>());
                    //将该节点插入到对应的list的头部
                    currentMap.get(menuList.get(n).getParentId()).add(0, menuList.get(n));
                }
            }
            if (n < 0) {
                return menuList;
            } else {
                return mergeList(new ArrayList<>(menuList.subList(0, n + 1)), menuList.get(n).getLevel(), currentMap);
            }
        }
    
    
    }
    

    相关文章

      网友评论

        本文标题:java 树状结构数据的对象封装

        本文链接:https://www.haomeiwen.com/subject/cqaaektx.html