Java实现n级树对象的封装

匿名 (未验证) 提交于 2019-12-02 21:53:52

项目开发中经常会遇到多叉树的展示,最为常见的便是组织机构图以及省市县结构图,
通常做法是接收服务器端返回来的JSON格式的数据,动态生成树形菜单节点。
动态生成树有两种思路:

  1. 异步加载节点,适用于节点数量很多的结构,通过zTree等插件封装的方法,传入指定的节点ID查询出当前节点下的子节点信息。
  2. 一次性生成全部树节点,适用于小数据量的结构。

今天的笔记记录的是第二种思路的实现方式,共两种

第一种为最常规的做法,将节点以节点编号为Key存入散列表,随后遍历散列表通过Key值与节点的parentId对应关系再构造出多叉树:

public class InfiniteLevelTreeUtil {     public static List<Node> getInfiniteLevelTree() {         // 读取层次数据结果集列表         List<Node> dataList = dao.getNodes();         // 将Node存入散列表         Map<String, Node> nodeMap = dataList.stream().collect(Collectors.toMap(Node::getId, node -> node));         // 根节点         List<Node> root = new ArrayList<>();         // 构造无序的多叉树         for(Map.Entry<String, Node> entry: nodeMap.entrySet()) {             Node node = entry.getValue();             if (node.getParentId().equals("-1")) {                 root.add(node);             } else {                 nodeMap.get(node.getParentId()).addChild(node);             }         }         return root;     } } // 节点Bean public class Node {     private String id;     private String name;     private String parentId;     private int order;     private Children children = new Children();     // ...get set 方法,构造方法      // 兄弟节点排序     public void sortChildren() {         if (children != null && children.getSize() != 0) {             children.sortChildren();         }     }     // 添加孩子节点     public void addChild(Node node) {         this.children.addChild(node);     } } // 子节点Bean public class Children {     private List<Node> list = new ArrayList<>();     // ...get set 方法,构造方法     public int getSize() {         return list.size();     }     public void addChild(Node node) {         list.add(node);     }     // 孩子节点排序     public void sortChildren() {         Collections.sort(list, new NodeOrderComparator());         for (Iterator<Node> it = list.iterator(); it.hasNext();) {             it.next().sortChildren();         }     } } // 节点排序Comparator public class NodeOrderComparator implements Comparator<Node>{     // 按照节点排序值进行排序     public int compare(Node n1, Node n2) {         return (n1.getOrder() < n2.getOrder() ? -1 : (n1.getOrder() == n2.getOrder() ? 0 : 1));     } }




第二种做法使用了递归,以parentId = '-1'(根节点)作为递归方法的入口,构造多叉树。

public class InfiniteLevelTreeUtil {     // 入口方法     public List<Node> getInfiniteLevelTree(List<Node> nodeList) {         List<Node> list = new ArrayList<>();         // 遍历节点列表         for (Node node : nodeList) {             if (node.getParentId().equals("-1")) {                 // parentID为-1(根节点)作为入口                 node.setChildren(getChildrenNode(node.getId(), nodeList));                 list.add(node);             }         }         // 排序         list.sort(new NodeOrderComparator());         return list;     }      // 获取子节点的递归方法     public List<Node> getChildrenNode(String id, List<Node> nodeList) {         List<Node> lists = new ArrayList<>();         for (Node node : nodeList) {             if (node.getParentId().equals(id)) {                 // 递归获取子节点                 node.setChildren(getChildrenNode(node.getId(), nodeList));                 lists.add(node);             }         }         // 排序         lists.sort(new NodeOrderComparator());         return lists;     } }  // 节点Bean public class Node {     private String id;     private String name;     private String parentId;     private int order;     private List<Node> children = new ArrayList<>();     // ...get set 方法,构造方法 }  // 节点排序Comparator public class NodeOrderComparator implements Comparator<Node>{     // 按照节点排序值进行排序     public int compare(Node n1, Node n2) {         return (n1.getOrder() < n2.getOrder() ? -1 : (n1.getOrder() == n2.getOrder() ? 0 : 1));     } }


节点列表如下(id,name,pid,order):

Node n1 = new Node("0", "根节点", "-1", 0); Node n2 = new Node("01", "一级子节点", "0", 0); Node n3 = new Node("011", "二级子节点1", "01", 3); Node n4 = new Node("012", "二级子节点2", "01", 2); Node n5 = new Node("013", "二级子节点3", "01", 1); Node n6 = new Node("0131", "三级子节点1", "013", 1); Node n7 = new Node("0132", "三级子节点2", "013", 1);

运行方法后得到的树结构的JSON串如下:

{       id : '0',        name: '根节点',        children : [{           id : '01',            name: '一级子节点',            children : [             {                   id : '011',                    name: '二级子节点1',                 children:[]             },             {                   id : '012',                    name: '二级子节点2',                 children:[]             },             {                   id : '013',                    name: '二级子节点3',                    children : [                     {                           id : '0131',                            text : '三级子节点1'                     },                     {                           id : '01312',                            text : '三级子节点2'                     }                 ]              }         ]       }]   }

以上,实现了无线级树节点的构造

java实现构造无限层级树形菜单
利用多叉树实现Ext JS中的无限级树形菜单(一种构建多级有序树形结构JSON的方法)





标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!