• 树形结构数据存储方案的选择和java list转tree


    树形结构数据存储方案

    Adjacency List:每一条记录存parent_id
    Path Enumerations:每一条记录存整个tree path经过的node枚举
    Nested Sets:每一条记录存 nleft 和 nright
    Closure Table:维护一个表,所有的tree path作为记录进行保存。

    各种方法的常用操作代价见下图

     
    一般来说,数据量小,采用适合邻接表存储设计,简单灵活,而大部分情况下都不会有太大的数据,主要用于种类树、菜单树。

    邻接表再程序中的使用:直接查询所有,然后构建树形结构数据。有序数据构建树,层级之间是有序的。可通过sql查询排序。

    java list转tree

    TreeNode接口

    package klg.common.tree;
    
    import java.io.Serializable;
    import java.util.List;
    /**
     * 
     * @author klguang
     *
     * @param <ID>
     */
    public interface TreeNode<ID extends Serializable> {
    
        public ID getId();
        public ID getParentId();
        
        public <T extends TreeNode<ID>> void setChildren(List<T> children);
        
    }
    

      

    TreeHelper工具类

    package klg.common.tree;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    /**
     * 
     * @author klguang
     *
     */
    public class TreeHelper {
    
        /**
         * 
         * @param parentID
         *            null 为根节点
         * @param nodeList
         * @param sort
         * @return
         */
        public static <ID extends Serializable,T extends TreeNode<ID>> List<T> buildTree(ID parentID, List<T> nodeList) {
            // 根节点列表
            List<T> list = new ArrayList<>();
            // 顺序遍历节点列表,如果之前是有序的,那么构建树后同层级之间有序
            for (int i=0; i<nodeList.size(); i++) {
                T node = nodeList.get(i);
                //递归入口, String.valueOf防止null值
                if (String.valueOf(node.getParentId()).equals(String.valueOf(parentID))) {
                    // parentID作为入口
                    List<T> children = buildTree(node.getId(), nodeList);
                    node.setChildren(children);
                    list.add(node);
                }
            }
            
            return list;
        }        
    }
    

      

    案例easyui tree

    package klg.common.tree;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.persistence.Access;
    import javax.persistence.AccessType;
    import javax.persistence.Column;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.MappedSuperclass;
    import javax.persistence.Transient;
    
    /**
     * 
     * @author klguang
     *
     */
    @MappedSuperclass
    @Access(AccessType.FIELD)
    public abstract class EasyUITreeNode<ID extends Serializable> implements Serializable, TreeNode<ID> {
    
        private static final long serialVersionUID = 850845227481354764L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private ID id;
    
        @Column(name = "parent_id")
        private ID parentId;
    
        @Column(name = "name", nullable = false)
        private String name;
    
        @Column(name = "icon_cls")
        private String iconCls;
    
        @Column(name = "state")
        private String state;
    
        @Column(name = "order_num")
        private Integer orderNum;
    
        @SuppressWarnings("rawtypes")
        @Transient
        List children = new ArrayList<>();
    
        /**
         * easyui treegrid 需求格式
         * 
         * @return
         */
        public String getText() {
            return this.name;
        }
    
        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 String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getIconCls() {
            return iconCls;
        }
    
        public void setIconCls(String iconCls) {
            this.iconCls = iconCls;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    
        public Integer getOrderNum() {
            return orderNum;
        }
    
        public void setOrderNum(Integer orderNum) {
            this.orderNum = orderNum;
        }
    
        @SuppressWarnings("unchecked")
        public <T extends TreeNode<ID>> List<T> getChildren() {
            return children;
        }
    
        public<T extends TreeNode<ID>> void setChildren(List<T> children) {
            this.children = children;
        }
    
    }
    

      

    使用方法

    easyui tree实现类

    public class Permission extends EasyUITreeNode<Long> {
        //fields
    }

    构建树

        public List<Permission> findAll(){
            Sort sort = new Sort(Direction.ASC,"orderNum");
            List<Permission> listData=permissionService.findList(sort);
            
            return TreeHelper.<Long,Permission>buildTree(null, listData);
        }
  • 相关阅读:
    2019-2020-1 20199329《Linux内核原理与分析》第十二周作业
    2019-2020-1 20199329《Linux内核原理与分析》第十一周作业
    2019-2020-1 20199329《Linux内核原理与分析》第九周作业
    2019-2020-1 20199329《Linux内核原理与分析》第八周作业
    PHP基础学习笔记5
    MYSQL内置函数【转】
    PHP基础学习笔记3
    常用端口大全【转】
    NMAP输出结果中CPE的含义【转】
    探测主机信息
  • 原文地址:https://www.cnblogs.com/klguang/p/9850413.html
Copyright © 2020-2023  润新知