精华内容
下载资源
问答
  • 文章目录 目录 文章目录 ...使用递归来获取子节点,在递归的过程中将已添加到树结构中的数据剔除,减少递归调用的次数 2.实现 代码下载链接: Menu内部类定义如下 @Data static class ..

    文章目录

     

    前言

    由于在做前端动态路由时,需要将后端的数据转为tree便于前端构造Vue Router


    一、开发环境

    • JDK11(使用了forEach代替循环)

    二、具体使用

    1.思路

    使用递归来获取子节点,在递归的过程中将已添加到树结构中的数据剔除,减少递归调用的次数

    2.实现

    代码下载链接:https://download.csdn.net/download/weixin_38500202/13214868

     Menu内部类定义如下

        @Data
        static class Menu {
            private Integer id;
    
            /**
             * 父节点Id
             */
            private Integer parentId;
    
            /**
             * 菜单名
             */
            private String menuName;
    
            List<Menu> children;
        }

     具体的实现方法如下

        public List<Menu> list2Tree(List<Menu> list, Integer pId) {
            List<Menu> tree = new ArrayList<>();
            Iterator<Menu> it = list.iterator();
            while (it.hasNext()) {
                Menu m = it.next();
                if (m.parentId == pId) {
                    tree.add(m);
                    // 已添加的元素删除掉
                    it.remove();
                }
            }
            // 寻找子元素
            tree.forEach(n -> n.children = list2Tree(list, n.id));
            return tree;
        }

    二、结果

    输出结果如下所示


    三、总结

    递归yyds!🐂

    展开全文
  • JAVA数据结构与算法(三) 定义 (Tree)是n(n≥0)个结点的有限集T,并且当n>0时满足下列条件: (1)有且仅有一个特定的称为根(Root)的结点; (2)当n>1时,其余结点可以划分为m(m>0)个互不相交的有限集T1、...

    JAVA数据结构与算法(三)树

    定义
    树(Tree)是n(n≥0)个结点的有限集T,并且当n>0时满足下列条件:
    (1)有且仅有一个特定的称为根(Root)的结点;
    (2)当n>1时,其余结点可以划分为m(m>0)个互不相交的有限集T1、T2 、…、Tm,每个集Ti(1≤i≤m)均为树,且称为树T的子树(SubTree)。
    特别地,不含任何结点(即n=0)的树,称为空树。
    树的术语
    1.结点:包含了数据项和指向其他结点的分支
    2.结点的度:结点所拥有的子树棵树。例如上图中,B的度为1,C的度为2,D的度为3
    3.叶结点&终端结点:即度为0的结点,例如上图中,F,G,H,I,J均为叶结点
    4.分支结点&非终端结点:除了叶结点以外的其他结点

    5.子女结点:若结点x有子树,则子树的根结点即为结点x的子女。例如上图中,A有两个子女,分别为B,C
    6.父结点:若结点x有子女,它即为子女的父结点
    7.根结点:没有父结点的结点称为根结点
    8.兄弟结点:同一父结点的子女互称为兄弟。例如上图中,D,E,F互为兄弟
    9.祖先结点:从根结点到该结点所经历分支上的所有结点。例如上图中,G的祖先结点为A,B,D
    10.子孙结点:某一结点的子女,以及这些子女的子女都是该结点的子孙。例如上图中,结点B的子孙D,G
    11.结点所处的层次:从根到该结点所经路径上的分支条数.根结点在第1层,它的子女在第二层。树中任一12.结点的层次为它的父结点的层次加1。结点所处层次亦称为结点的深度
    13.树的高度:叶结点的高度为1,非叶结点的高度等于它子女结点高度的最大值加1。该树的高度为4

    14.树的度:树中结点的度的最大值。例如上图中该树的高度为3
    树的存储与表示
    顺序存储:将数据结构存储在固定的数组中,然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储
    在这里插入图片描述
    在这里插入图片描述
    链式存储
    在这里插入图片描述
    常见的一些树的应用场景
    1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
    2.路由协议就是使用了树的算法
    3.mysql数据库索引
    4.文件系统的目录结构
    5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构

    创建一颗树

    class TreeNode{
    	int data;
    	TreeNode leftChild;
    	TreeNode rightChild;
    }
    

    省略get set方法
    树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(traversal)。
    那么树的两种重要的遍历模式是 深度优先遍历和广度优先遍历, 深度优先一般用 递归 ,广度优先一般用 队列 。一般情况下能用递归实现的算法大部分也能用堆栈来实现。

    深度优先遍历
    1.1 对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
    深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)
    先序遍历
    在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树
    根节点->左子树->右子树

    	public static void preOrder(Node head){
    		if(head==null){
    			return;
    		}
    		System.out.println(head.getData()+" ");
    		preOrder(head.leftChild);
    		preOrder(head.rightChild);
    	}
    

    中序遍历
    在中序遍历中,我们递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树
    左子树->根节点->右子树

    public static void  inOrder(Node head){
    		if(head==null){
    			return;
    		}
    		preOrder(head.leftChild);
    		System.out.println(head.getData()+" ");
    		preOrder(head.rightChild);
    	}
    

    后序遍历
    在后序遍历中,我们先递归使用后序遍历访问左子树和右子树,最后访问根节点
    左子树->右子树->根节点

    	public static void  posOrder(Node head){
    		if(head==null){
    			return;
    		}
    		preOrder(head.leftChild);
    		preOrder(head.rightChild);
    		System.out.println(head.getData()+" ");
    	}
    

    广度优先遍历
    从树的root开始,从上到下从从左到右遍历整个树的节点

    public void levelOrderTraversal(Node node){
          if(node==null){
                System.out.print("empty tree"); 
                return;
          }
          ArrayList<Integer> lists=new ArrayList<Integer>();
          Queue<Node> queue=new LinkedList<Node>();
          queue.offer(node);
          while(!queue.isEmpty()){
        	  Node tree=queue.poll();
              if(tree.leftChild!=null){
                  queue.offer(tree.leftChild);
              }
              if(tree.rightChild!=null){
                  queue.offer(tree.rightChild);
              }
              lists.add((Integer) tree.data);
          }
      }
    
    展开全文
  • 哈夫曼也称作最优二叉树,当中的节点带了权重信息了,带权路径长度最小的二叉树叫做最优二叉树。带权路径长度=sum(权重*度)。sum代表每个节点的之和。加入有如下带权重的节点。  权重分别是1、5、8、4。那么...

    感谢suhuanzheng7784877的分享,原文链接地址:点击打开链接

    1.       哈夫曼树

    哈夫曼树也称作最优二叉树,当树中的节点带了权重信息了,带权路径长度最小的二叉树叫做最优二叉树。带权路径长度=sum(权重*度)。sum代表每个节点的之和。加入有如下带权重的节点。

     权重分别是1、5、8、4。那么关于这些零散的节点,最优二叉树该如何构建呢?

    首先先将离散节点从小到大升序排序

    第二从离散节点中在挑选排序前两个节点当做一个新的父节点的两个子节点

    第三从离散的节点中去除刚刚使用的两个节点

    第四重复第二和第三步骤,直到所有离散节点剔除完毕。哈夫曼树就构建完成

    用图形演示过程如下

     可以看出所有的叶子节点就是之前的离散节点,如果在采用广度遍历法遍历此树。那么遍历的过程实际上就是最短遍历路径的遍历过程

    2.       哈夫曼树的使用场景

    其实哈夫曼树使用场景还真不少,例如apache负载均衡的按权重请求策略的底层算法、咱们生活中的路由器的路由算法、利用哈夫曼树实现汉字点阵字形的压缩存储(http://www.cnki.com.cn/Article/CJFDTotal-LYGY200504016.htm)、快速检索信息等等底层优化算法,其实核心就是因为目标带有权重、长度远近这类信息才能构建哈夫曼树模型。

    3.       实现哈夫曼树

    要想实现哈夫曼树其实就是将一堆零散的节点信息构建成一颗最优二叉树,之后再按广度优先遍历它。

    实现哈夫曼树其实就是构建哈夫曼树的过程,原理其实上面已经说了,这里再重复一下。

    首先先将离散节点从小到大升序排序

    第二从离散节点中在挑选排序前两个节点当做一个新的父节点的两个子节点

    第三从离散的节点中去除刚刚使用的两个节点

    第四重复第二和第三步骤

    代码以及测试程序如下

    Java代码  收藏代码
    1. package tree;
      import java.util.ArrayDeque;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Queue;
      /**
       * 哈夫曼树
       * 
       * @author liuyan
       */
      public class HuffmanTree {
      /**
      * 节点实体
      */
      public static class Node<T> {
      // 数据
      T data;
      // 权重
      int power;
      Node<T> leftNode;
      Node<T> rightNode;
      public Node(T data, int power) {
      this.data = data;
      this.power = power;
      }
      @Override
      public String toString() {
      return "[data:" + data + "   power:" + power + "]";
      }
      @SuppressWarnings("unchecked")
      public boolean compareTo(Node node) {
      if (this.power < node.power) {
      return true;
      }
      return false;
      }
      }


      /**
      * 将集合将序排序

      * @param <T>
      * @param <E>

      * @param list
      */
      @SuppressWarnings("unchecked")
      public static void sort(List<Node> list) {
      for (int i = 0; i < list.size() - 1; i++) {
      for (int j = i + 1; j < list.size(); j++) {
      if (list.get(i).compareTo(list.get(j))) {
      // 交换数组中的元素位置
      Node node = list.get(i);
      list.set(i, list.get(j));
      list.set(j, node);
      }
      }
      }
      }
      /**
      * 创建哈夫曼树

      * @param list
      * @return
      */
      @SuppressWarnings("unchecked")
      public static Node createHuffmanTree(List<Node> list) {
      while (list.size() > 1) {
      sort(list);
      Node left = list.get(list.size() - 1);
      Node right = list.get(list.size() - 2);
      Node parent = new Node("父节点", left.power + right.power);
      parent.leftNode = left;
      parent.rightNode = right;
      list.remove(list.size() - 1);
      list.remove(list.size() - 1);
      list.add(parent);
      }
      return list.get(0);
      }


      @SuppressWarnings("unchecked")
      public static List<Node> deepFirst(Node root) {
      List<Node> list = new ArrayList<Node>();
      /*
         java.util.ArrayDeque 类提供了可调整大小的阵列,并实现了Deque接口。以下是关于阵列双端队列的要点:
      数组双端队列没有容量限制,使他们增长为必要支持使用。
      它们不是线程安全的;如果没有外部同步。
      不支持多线程并发访问。
      null元素被禁止使用在数组deques。
      它们要比堆栈Stack和LinkedList快。
      此类及其迭代器实现Collection和Iteratorinterfaces方法可选。
      */
      Queue<Node> queue = new ArrayDeque<Node>();
      queue.add(root);
      while (!queue.isEmpty()) {//判断队列是否为空
      list.add(queue.peek());//此方法检索,但是不移除此deque队列表示的队列的头部,如果此deque队列为空,则返回null。
      Node twoLinkNode = queue.poll();//此方法检索并移除此deque队列表示的队列的头部,如果此deque队列为空,则返回null。
      if (twoLinkNode.leftNode != null) {
      queue.add(twoLinkNode.leftNode);
      }   
      if (twoLinkNode.rightNode != null) {
      queue.add(twoLinkNode.rightNode);
      }
      }
      return list;
      }


      /**
      * @param args
      */
      public static void main(String[] args) {
      List<Node> list = new ArrayList<Node>();
      Node<String> node1 = new Node<String>("东方不败", 8);
      Node<String> node2 = new Node<String>("风清扬", 5);
      Node<String> node3 = new Node<String>("岳不群", 4);
      Node<String> node4 = new Node<String>("左冷禅", 1);
      list.add(node1);
      list.add(node2);
      list.add(node3);
      list.add(node4);
      Node root = createHuffmanTree(list);
      System.out.println(deepFirst(root));
      }
      }

     测试结果是

    Java代码  收藏代码
    1. [[data:父节点   power:18], [data:东方不败   power:8], [data:父节点   power:10], [data:父节点   power:5], [data:风清扬   power:5], [data:左冷禅   power:1], [data:岳不群   power:4]]  


    如果有什么不清楚或者有啥疑问意见可以加我QQ/微信  208017534  / qiang220316,欢迎一起交流一起进步。


    展开全文
  • Vue Router 分为静态路由和动态路由,权限这块一般有几个静态页面路由用来对权限路由的增删改查,创建出来的路由会被存入到数据库内,当某个用户登录了,...package java将线性结构的菜单转换为vuetree型结构菜单; /

    Vue Router 分为静态路由和动态路由,权限这块一般有几个静态页面路由用来对权限路由的增删改查,创建出来的路由会被存入到数据库内,当某个用户登录了,我们就会查询它的权限,从数据库中拿到属于他的路由数据渲染到页面上。这就是动态路由,动态路由的数据来源于后端,静态路由的数据是前端vue直接写死的。
    接下来我们看看后端如何查询出数据,并且将数据库查询出的线性结构的数据改造成Tree型结构的返回给前端使用。

    1.模拟数据库查询的数据

    package java将线性结构的菜单转换为vuetree型结构菜单;
    /**
     * 模拟数据库查询的数据
     * 父子全在一起的数据
     * @author T011921
     *
     */
    public class DataBean {
    	//private String PRVG_TP_CODE; 
    	private Object PRN_PRVG_ID; //父级id 顶级为0
    	private String PRVG_NAME;//名称
    	private String PRVG_ID; //父亲子集id --对应孩子的父级id
    	private String COMPONENT; //菜单对应的模块路由
    	private String URL; //访问地址
    	public Object getPRN_PRVG_ID() {
    		return PRN_PRVG_ID;
    	}
    	public void setPRN_PRVG_ID(Object pRN_PRVG_ID) {
    		PRN_PRVG_ID = pRN_PRVG_ID;
    	}
    	public String getPRVG_NAME() {
    		return PRVG_NAME;
    	}
    	public void setPRVG_NAME(String pRVG_NAME) {
    		PRVG_NAME = pRVG_NAME;
    	}
    	public String getPRVG_ID() {
    		return PRVG_ID;
    	}
    	public void setPRVG_ID(String pRVG_ID) {
    		PRVG_ID = pRVG_ID;
    	}
    	public String getCOMPONENT() {
    		return COMPONENT;
    	}
    	public void setCOMPONENT(String cOMPONENT) {
    		COMPONENT = cOMPONENT;
    	}
    	public String getURL() {
    		return URL;
    	}
    	public void setURL(String uRL) {
    		URL = uRL;
    	}
    	@Override
    	public String toString() {
    		return "DataBean [PRN_PRVG_ID=" + PRN_PRVG_ID + ", PRVG_NAME=" + PRVG_NAME + ", PRVG_ID=" + PRVG_ID
    				+ ", COMPONENT=" + COMPONENT + ", URL=" + URL + "]";
    	}
    	public DataBean(Object pRN_PRVG_ID, String pRVG_NAME, String pRVG_ID, String cOMPONENT, String uRL) {
    		super();
    		PRN_PRVG_ID = pRN_PRVG_ID;
    		PRVG_NAME = pRVG_NAME;
    		PRVG_ID = pRVG_ID;
    		COMPONENT = cOMPONENT;
    		URL = uRL;
    	}
    	public DataBean() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	
    	
    	
    }
    
    
    package java将线性结构的菜单转换为vuetree型结构菜单;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class Data {
    	public static List<DataBean> getData() {
    		List<DataBean> list = new ArrayList<>();
    		
    		list.add(new DataBean("0","顶级父级1","10","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("0","顶级父级2","11","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("0","顶级父级3","12","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("0","顶级父级4","13","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("0","顶级父级5","14","@/ul.vue","/aa.jsp"));
    		
    		list.add(new DataBean("10","子集","21","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("10","子集","22","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("10","子集","23","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("12","子集","31","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("12","子集","32","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("14","子集","33","@/ul.vue","/aa.jsp"));
    		
    		list.add(new DataBean("21","孙子集","55","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("21","孙子集","56","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("21","孙子集","57","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("22","孙子集","58","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("22","孙子集","59","@/ul.vue","/aa.jsp"));
    		list.add(new DataBean("23","孙子集","59","@/ul.vue","/aa.jsp"));
    		return list;
    	}
    	
    }
    
    

    数据库存储的格式是子集父级都存在一张表里,没条数据都有一个父级id和子集id。子集id对应它孩子的父级id,当然顶级的父级id为0;下面我们将它通过递归的方式改成Tree型结构的数据

    注意:代码里说的两种解决方案,其实都不是最方便的,最方便的是,我们在sql上处理,将我们的用到的需要分组的那个字段用to_char(),转换成字符串,这样不管我们定义String或者Object,都不会产生bug,也不用计较使用方式一或者方式二了。
    所说的bug:我们分组使用的字段是数字,虽然我们认为它是字符串但是java在查出来时转换为Bigdecimal 对象了,我们分组之后,如果牵扯到比较方法就会报错。int类型比较或者字符串类型比较都会报错 ;这时候我们只需要在sql上把这个字段to_char()就行了

    package java将线性结构的菜单转换为vuetree型结构菜单;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    /**
     * 本类作用:前端想做动态路由,数据从后端获取,
     * 后端的menu 数据全在一张表里,根节点的父节点为0,它的子节点对应孩子的父节点,孩子的子节点对应孙子的父节点,以此类推的一种数据格式。
     * 后端获取这样线性结构的数据,需要将这些数据处理成Tree型结构的数据返回给前端,前端直接用就可以了。
     * 本类牵扯到java8的分组,和递归的方式,实现了树形结构。有了这种思想,可以仿照做各种tree型结构的数据出来
     * @author T011921
     *
     */
    public class SysRouterUtil {
    	
    	/**
    	 * 在第二步分组之后获取父节点集合时有个bug
    	 * glist.get("0")根本取不出来数据,原因是请求参数中的map的值定义的是Object,我们定义父子级节点一般都会用数字。从数据库查出来之后这个数字类型被转换为Object对象,debug是BigDecemal,所以map.get("0")是取不出来的。
    	 * 解决方案1.mybatis 取数据时,定义为List<Map<String,String>>类型的,这个方法的请求参数和分组的返回值也改成Map<Object, List<Map<String, String>>> 类型,这样就可以直接取了glist.get("0");
    	 * 
    	 * 解决方案2.依旧使用 List<Map<String,Object>>的方式查询。在分过组之后 使用forEach语法迭代。
    	 * 
    	 * @param list //数据库查出来的menu数据
    	 * @return
    	 * @throws Exception
    	 */
    	public static List<Map<String,Object>> getRouterMenu(List<Map<String,Object>> list) throws Exception{
    		List<Map<String,Object>> result = new ArrayList<>();
    		try {
    			if(list.size()>0) {
    				//1.分组:使用java8的方式,父id(PRN_PRVG_ID)的字段进行分组
    				Map<Object, List<Map<String, Object>>> glist = list.stream().collect(Collectors.groupingBy(e ->e.get("PRN_PRVG_ID")));
    				//2.取出顶层的根节点的所有数据集合,父id的根节点都为0的。这里有个bug。
    				//方案1: 我这里不会报错,因为我的数据是从java构造出来的,节点是字符串数字,如果从数据库查询的话,会给你转成BigDecmal对象,你要么将数据value定义为String。要么用方案2 将k转换为字符串在去判断为0。使用当前的集合
    				List<Map<String, Object>> parentlist = glist.get("0");//所有父级的数据
    				for(Map<String,Object> plist : parentlist) {
    				    //3. 遍历父节点的所有数据,使用LinkedHashMap,使最终的结果结构层次更加分明
    					Map<String,Object> parent = new LinkedHashMap<>();
    					parent.put("path", plist.get("URL"));
    					parent.put("name", "");
    					parent.put("meta",setMeta(plist.get("PRVG_NAME").toString(),true));
    					parent.put("hideChildrenInMenu", true);
    					parent.put("component", plist.get("COMPONENT"));
    					parent.put("children", getChildren(glist,plist.get("PRVG_ID")));//这里去迭代当前所有子节点,将最终结果存入父节点的children 属性里
    					result.add(parent);
    				}
    				
    				//方案2: 
    //				glist.forEach((k,mylist) ->{
    //					//在这里将k转换为字符串,然后和0做匹配就行了
    //					if("0".equals(k.toString())) {
    //						for(Map<String,Object> plist : mylist) {
    //						    //3. 遍历父节点的所有数据,使用LinkedHashMap,使最终的结果结构层次更加分明
    //							Map<String,Object> parent = new LinkedHashMap<>();
    //							parent.put("path", plist.get("URL"));
    //							parent.put("name", "");
    //							parent.put("meta",setMeta(plist.get("PRVG_NAME").toString(),true));
    //							parent.put("hideChildrenInMenu", true);
    //							parent.put("component", plist.get("COMPONENT"));
    //							parent.put("children", getChildren(glist,plist.get("PRVG_ID")));//这里去迭代当前所有子节点,将最终结果存入父节点的children 属性里
    //							result.add(parent);
    //						}
    //					}
    //					
    //				});
    //				
    			}
    		} catch (Exception e) {
    			throw new Exception("数据解析异常");
    		}
    		return result;
    	}
    
    	/**
    	 * 递归迭代是否有子节点
    	 * 递归说明,第一次父节点调用,去根据父传来的它所对应的子节点id,去判断分组里有没有包含这个key,包含了说明它存在孩子,不包含,返回一个空数组;
    	 * 		  如果包含,就根据当前传来的父级id,取出对应的所有子集合
    	 * 		 遍历这个子集合;设置当前子的router信息,当设置为chlidren的时候迭代该函数,传入当前子数剧的子节点,接着迭代它的下面有没有孩子,依次类推,当最后一个孩子被迭代出来的时候,
    	 * 		查询出它已经没有孩子了返回一个空数组给最后一个孩子的children,然后在接着循环最后一个孩子的兄弟级,当最后一个孩子的兄弟级也迭代完之后,依次类推,开始一级一级的往上级闭合。
    	 * 		最终所有的子节点数据返回给最大的父节点的children,存入到最终的list中,开始迭代第二个父级...最终形成一个tree型结构的Router 
    	 * @param glist //分组之后的源菜单数据
    	 * @param plist // 当前循环的父节点
    	 */
    	private static List<Map<String,Object>> getChildren(Map<Object, List<Map<String, Object>>> glist, Object prvg_id) {
    		List<Map<String,Object>> children = new ArrayList<>();
    		try {
    			// 1.通过传入的prvg_id 判断组里是否存在子节点,
    			if(glist.containsKey(prvg_id)) {
    				//存在子节点,循环取出子节点的prvgid,
    				List<Map<String, Object>> childList = glist.get(prvg_id);//所有子级的数据
    				for(Map child : childList) {
    					//3.通过顶层父级的prvg_id,递归迭代当前父级的所有子集,子孙级
    					Map<String,Object> childMap = new LinkedHashMap<>();
    					childMap.put("path", child.get("URL"));
    					childMap.put("name", "");
    					childMap.put("meta",setMeta(child.get("PRVG_NAME").toString(),true));
    					childMap.put("hideChildrenInMenu", true);
    					childMap.put("component", child.get("COMPONENT"));
    					childMap.put("children", getChildren(glist,child.get("PRVG_ID")));
    					children.add(childMap);
    				}
    				
    			}
    		}catch (Exception e) {
    			e.printStackTrace();
    		}
    	
    		return children;
    	}
    	
    	
    	
    	private static Object setMeta(String string, boolean b) {
    		Map<String,Object> meta = new HashMap<String,Object>();
    		meta.put("title", string);
    		meta.put("keepAlive", b);
    		return null;
    	}
    
    	
    	//测试
    	public static void main(String[] args) {
    		//简单构造下数据,可以从数据库中取出
    		List<DataBean> list =Data.getData();
    		List<Map<String,Object>> listmap= new ArrayList<>();
    		// 将bean转换为map
    		for(DataBean bean : list) {
    			Map<String,Object> map = new HashMap<>();
    			map.put("PRN_PRVG_ID", bean.getPRN_PRVG_ID());
    			map.put("PRVG_ID", bean.getPRVG_ID());
    			map.put("COMPONENT", bean.getCOMPONENT());
    			map.put("PRVG_NAME", bean.getPRVG_NAME());
    			map.put("URL", bean.getURL());
    			listmap.add(map);
    			System.out.println("源数据--" + map);
    		}
    		//存放Vue Router的集合
    		List<Map<String,Object>> result = new ArrayList<>();
    		try {
    			result = SysRouterUtil.getRouterMenu(listmap);
    			for(Map r : result) {
    				System.out.println("----" + r);
    			}
    		} catch (Exception e) {
    			System.out.println(e.getMessage());
    			e.printStackTrace();
    		}
    	}
    	
    }
    
    

    结果传给前端就行了:

    {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}]}]}
    ----{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}
    ----{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}, {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}]}
    {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}
    {path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[{path=/aa.jsp, name=, meta=null, hideChildrenInMenu=true, component=@/ul.vue, children=[]}]}
    
    展开全文
  • 前缀(Trie)原理及Java实现

    万次阅读 2017-05-02 15:43:36
    前缀树的结构Trie树,又叫字典树、前缀树(Prefix Tree)、单词查找树或键树,是一种多叉树结构。如下图: 上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”...
  • 大学四年零基础自学Java的路线

    万次阅读 多人点赞 2020-09-02 12:14:16
    系统层面的优化很多时候会很有限,你可能会尝试从算法,或者优化数据结构去优化,你看到了HashMap的源码,想去了解红黑,然后在算法网上看到了二叉树搜索和各种常见的算法问题,刷多了,你也能总结出精华所在,...
  • 最短路径的概念 最短路径的问题是比较典型的应用问题。在图中,确定了起始点和终点之后,一般情况下都可以有很多条路径来连接两者。...【数据结构】图(邻接矩阵、邻接表)的JAVA代码实现 。  
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    文章目录Java 基础Head First JavaJava 核心技术卷一Java 编程思想设计模式Head First 设计模式图解设计模式设计模式重学 Java 设计模式Java 进阶Java 并发编程实战Java 并发编程艺术Java 并发编程之美图解Java多...
  • java递归查询数据库

    千次阅读 2018-08-21 21:56:31
    场景描述 :每个应用(最顶层,的根) 下面是多级菜单 每个菜单下是多个按钮(最下层,叶子结点) 关联关系 id和pid 根节点 pid为空,可根据type=APP查询出根节点 查询出所有根节点,然后递归查出子孙节点 ...
  • 哈希总结-java

    2019-04-19 15:42:36
    哈希java实现 节点 哈希 哈希的应用 哈希的理论基础 质数分辨定律 这个定理可以简单的表述为:n个不同的质数可以“分辨”的连续整数的个数和他们的乘积相等。“分辨”就是指这些连续的整数不可能有...
  • 说明:本文中只是一个记录,后台返回递归数据 tree实体: import ... import lombok.Getter; import lombok.Setter;...import java.util.List; @Setter @Getter public class SfEntityList {...
  • 结构工具类

    2019-01-04 20:48:12
    * 基层结构实体类 * 必备属性:id,parentId,childsList */ @Data public class BaseTreeObj implements Serializable { private static final long serialVersionUID = 1L; private String id; p...
  • 底层使用的红黑 7.java BIO NIO AIO 序列化 字节操作:使用inputStream和outPutSream实现,字节是传输和存储的最小单位 字符操作:inputStreamReader:将字节流解码成字符流 OutPutStramWriter:将字符流编码成...
  • 上一篇文章我发布了Java后端的100道高频面试题(实际是90道)。大家如果看过这90道题,会发现一般常规的面试问题可以说都覆盖到了,看完应该还有一个感觉,每一道题都不是一二句话能简单讲完的,如果能把这些面试题...
  • 一、数据结构 什么是数据结构? 简单地说,数据结构是以某种特定的布局方式存储数据的容器。这种“布局方式”决定了数据结构对于某些操作是高效的,而对于其他操作则是低效的。首先我们需要理解各种数据结构,才能...
  • java

    千次阅读 2020-05-21 07:40:47
    Java 面试宝典 2020 版 前言…13 一. Java 基础部分…14 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? …14 2、Java 有没有 goto?..14 3、说说&和&&的区别。 …14 4、switch ...
  • Java笔试面试-Java 分布式框架面试总结

    万次阅读 多人点赞 2019-09-26 15:24:23
    答:Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 10.Dubbo 有哪些特性? 答:Dubbo 特性如下: 面向接口代理...
  • 赫夫曼、赫夫曼编码和JAVA实现

    千次阅读 2014-09-01 16:39:17
    学习赫夫曼,从问题引入,下来看问题的
  • 偶然听到xxx同事接到一个网关性能优化任务【路由匹配优化】,正好在复习数据结构这块的知识,于是研究了下,如果是我,我怎么做这块的优化? 思考 既然是网关性能优化,无疑是为了提高网关性能,在网关进行请求代理...
  • 阿里Java面经大全(整合版)

    万次阅读 多人点赞 2018-08-03 16:10:12
    阿里巴巴,三面,java实习 昨天晚上11点打电话来,问我可以面试不,我说不可以,然后就约到了今天, 1.上来问我项目用的框架,然后问我springmvc里面有的参数的设定,问的是细节,然后问我如果传的多个值是一个...
  • 整理最新java面试宝典2019

    千次阅读 2020-02-06 12:14:57
    java面试宝典2019 参照:http://www.wityx.com/3.html 1、meta标签的作用是什么 2、ReenTrantLock可重入锁(和synchronized的区别)总结 3、Spring中的自动装配有哪些限制? 4、什么是可变参数? 5、什么是领域...
  • 谈消息总线的路由模型

    千次阅读 2015-03-18 22:24:03
    本文就基于RabbitMQ的路由模型的实现过程中遇到的一些问题进行了探讨,并谈到了形拓扑实现各种通信模型的权衡。
  • 瑞士计算机科学家Niklaus Wirth在1976年写了一本书,名为《算法+数据结构=编程》。 40多年后,这个等式仍被奉为真理。这就是为什么在面试过程中,需要考察软件工程师对数据结构的理解。 几乎所有...
  • 数据结构与算法-前缀(Trie) 一、前缀的应用 前缀是一种数据结构,用于检索字符串数据集中的键。这一高效的数据结构有多种应用: 自动补全 ​ 图 1. 谷歌的搜索建议 拼写检查 ​ 图2. ...
  • 我爱Java

    2021-02-25 08:41:02
    1、 Java 基础知识 1.1 重载和重写的区别 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。重写: 发生在父子类中,方法名、参数...
  • 文章目录1、类加载和实例化2、Java是值传递还是引用传递3、类加载的主要过程4、什么是GC5、简述垃圾回收过程6、内存泄漏7、导致内存泄漏的场景8、Java中堆和栈的区别9、ArrayList、LinkedList、Vector的区别10、...
  • java 笔记

    千次阅读 2013-10-06 08:53:23
    Java从入门到精通笔记 第0讲 开山篇 1. Java se J2se 桌面 Java ee J2ee 网络 Java me J2me 手机   2. SQL server Mysql Oracle   3. 学习软件编程的注意事项  1.高效愉快学习  2.先建立一...
  • Java面试题大全

    万次阅读 2020-10-25 15:53:37
    180.java的异常类层次结构 181.对jdk8新特征有什么了解? 182.java的类加载机制 183.原子类的实现 184.Error,Exception和RuntimeException的区别,作用又是什么? 185.sleep()和wait()区别是什么? Springboot(含...
  • (英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“”是因为它看起来像...
  • Java面筋

    千次阅读 2020-09-22 11:19:52
    JDK和JRE的区别 JDK是Java语言的软件开发工具包,是整个Java开发的核心,包括了Java运行环境、Java工具和Java基础类库 JRE是Java运行时环境,包括Java虚拟机、Java核心类库和支持文件 JDK = JRE + Java开发工具 JRE...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,969
精华内容 5,987
关键字:

java路由树结构

java 订阅