树形结构数据存储方案的选择和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);
    }

 

posted @ 2018-10-25 15:58  klguang  阅读(4342)  评论(0编辑  收藏  举报