1. 程式人生 > >樹形結構資料儲存方案的選擇和java list轉tree

樹形結構資料儲存方案的選擇和java list轉tree

樹形結構資料儲存方案

Adjacency List:每一條記錄存parent_idPath Enumerations:每一條記錄存整個tree path經過的node列舉Nested Sets:每一條記錄存 nleft 和 nrightClosure 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);
    }