程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 一個樹型通用接口,樹型通用接口

一個樹型通用接口,樹型通用接口

編輯:JAVA綜合教程

一個樹型通用接口,樹型通用接口


  項目中難免遇到使用樹型結構,如部門、菜單等。

  它們有共同的屬性:id,name,parentId,因此抽象出一個接口,然後使用一個工具類實現列表轉樹的功能。

  (其它這個是在另一個項目找到的,非原創,在此共享一下)

  看源碼:

  1、樹型結構接口TreeObject.java

import java.util.List;

/**
 * 這個是列表樹形式顯示的接口
 */
public interface TreeObject {

    Object getId();

    void setId(Object id);

    Object getParentId();

    void setParentId(Object parentId);

    String getName();

    void setName(String name);

    List getChildren();

    void setChildren(List children);

}

  2、樹型處理工具類TreeUtil.java

import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 把一個list集合,裡面的bean含有 parentId 轉為樹形式
 *
 */
public class TreeUtil {

    /**
     * 判斷兩個父ID是否相同
     * @param p1
     * @param p2
     * @return
     */
    private boolean isEqualsParentId(Object p1,Object p2){
        if(p1!=null && p1!=null){
            return p1.equals(p2);
        }else if(p1==null && p2 == null) {
            return true;
        }else if(p1==null && p2 != null) {
            if("".equals(p2.toString())){
                return true;
            }else{
                return false;
            }
        }else if(p1!=null && p2 == null) {
            if("".equals(p1.toString())){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    
    /**
     * 根據父節點的ID獲取所有子節點,該方法頂級節點必須為空
     * @param list 分類表
     * @param parentId 傳入的父節點ID
     * @return String
     */
    public List getChildTreeObjects(List<TreeObject> list,Object parentId) {
        List returnList = new ArrayList();
        if(list!=null&&list.size()>0) {
            for (Iterator<TreeObject> iterator = list.iterator(); iterator.hasNext(); ) {
                TreeObject t = (TreeObject) iterator.next();
                // 一、根據傳入的某個父節點ID,遍歷該父節點的所有子節點
                if (isEqualsParentId(t.getParentId(), parentId)) {
                    recursionFn(list, t);
                    returnList.add(t);
                }
            }
        }
        return returnList;
    }

    /**
     * 根據父節點的ID獲取所有子節點,該方法頂級節點可以不為空,非樹直接返回
     * @param list 分類表
     * @return String
     */
    public List<TreeObject> getChildTreeObjects(List<TreeObject> list) {
        if(list!=null&&list.size()>0) {
            List<TreeObject> topList=new ArrayList<>();
            List<TreeObject> subList=new ArrayList<>();

            Map<String,String> idMap=new HashMap<>();

            for (Iterator<TreeObject> iterator = list.iterator(); iterator.hasNext(); ) {
                //歸並所有list的id集合
                TreeObject t = (TreeObject) iterator.next();
                idMap.put(t.getId().toString(), t.getId().toString());
            }

            for (Iterator<TreeObject> iterator = list.iterator(); iterator.hasNext(); ) {
                //獲取最頂級的list
                TreeObject t = (TreeObject) iterator.next();
                if(t.getParentId()==null|| StringUtils.isEmpty(t.getParentId().toString())){
                    topList.add(t);
                }else{
                    String id=idMap.get(t.getParentId().toString());
                    if(StringUtils.isEmpty(id)){
                        topList.add(t);
                    }else{
                        subList.add(t);
                    }
                }
            }
            if(topList!=null&&topList.size()>0&&subList!=null&&subList.size()>0){
                List<TreeObject> resultList=new ArrayList<>();
                for (TreeObject t:topList) {
                    //將兒子級別的list歸並到頂級中
                    List<TreeObject> subOneList=new ArrayList<>();

                    for (TreeObject sub:subList) {
                        // 一、根據傳入的某個父節點ID,遍歷該父節點的所有子節點
                        if (isEqualsParentId(sub.getParentId(), t.getId())) {
                            recursionFn(subList, sub);
                            subOneList.add(sub);
                        }
                    }
                    t.setChildren(subOneList);


                    resultList.add(t);
                }
                return resultList;
            }else{
                return list;
            }
        }
        return list;
    }

    
    /**
     * 遞歸列表
     * @param list
     * @param t
     */
    private void  recursionFn(List<TreeObject> list, TreeObject t) {
        List<TreeObject> childList = getChildList(list, t);// 得到子節點列表
        t.setChildren(childList);
        for (TreeObject tChild : childList) {
            if (hasChild(list, tChild)) {// 判斷是否有子節點
                //returnList.add(TreeObject);
                Iterator<TreeObject> it = childList.iterator();
                while (it.hasNext()) {
                    TreeObject n = (TreeObject) it.next();
                    recursionFn(list, n);
                }
            }
        }
    }
    
    // 得到子節點列表
    private List<TreeObject> getChildList(List<TreeObject> list, TreeObject t) {
        
        List<TreeObject> tlist = new ArrayList<TreeObject>();
        Iterator<TreeObject> it = list.iterator();
        while (it.hasNext()) {
            TreeObject n = (TreeObject) it.next();
            if (isEqualsParentId(n.getParentId(),t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    } 
    List<TreeObject> returnList = new ArrayList<TreeObject>();
    /**
     * 根據父節點的ID獲取所有子節點
     * @param list 分類表
     * @param parentId 傳入的父節點ID
     * @param prefix 子節點前綴
     */
    public List<TreeObject> getChildTreeObjects(List<TreeObject> list, Object parentId,String prefix){
        if(list == null) return null;
        for (Iterator<TreeObject> iterator = list.iterator(); iterator.hasNext();) {
            TreeObject node = (TreeObject) iterator.next();
            // 一、根據傳入的某個父節點ID,遍歷該父節點的所有子節點
            if (isEqualsParentId(node.getParentId(),parentId)) {
                recursionFn(list, node,prefix);
            }
            // 二、遍歷所有的父節點下的所有子節點
            /*if (node.getParentId()==0) {
                recursionFn(list, node);
            }*/
        }
        return returnList;
    }
     
    private void recursionFn(List<TreeObject> list, TreeObject node,String p) {
        List<TreeObject> childList = getChildList(list, node);// 得到子節點列表
        if (hasChild(list, node)) {// 判斷是否有子節點
            returnList.add(node);
            Iterator<TreeObject> it = childList.iterator();
            while (it.hasNext()) {
                TreeObject n = (TreeObject) it.next();
                n.setName(p+n.getName());
                recursionFn(list, n,p+p);
            }
        } else {
            returnList.add(node);
        }
    }

    // 判斷是否有子節點
    private boolean hasChild(List<TreeObject> list, TreeObject t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
    
}

  3、使用示例

  以菜單為例,菜單對象實現TreeObject接口

  (@ApiModel、@ApiModelProperty不需要的,是用於生成API文檔的)

import com.mjwon.core.tree.TreeObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.io.Serializable;
import java.util.List;

@ApiModel(value = "菜單樹對象")
public class MenuTreeDto implements Serializable, TreeObject {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "菜單ID", example = "1", required = true)
    private String id;
    @ApiModelProperty(value = "菜單名稱", example = "菜單", required = true)
    private String menuName;
    @ApiModelProperty(value = "菜單類型", example = "1", required = true)
    private Short menuType;
    @ApiModelProperty(value = "菜單代碼", example = "1", required = true)
    private String menuCode;
    @ApiModelProperty(value = "父節點ID", example = "2", required = true)
    private String parentId;
    @ApiModelProperty(value = "排序", example = "2", required = false)
    private Long sortNo;
    @ApiModelProperty(value = "展開狀態", example = "1/0", required = true)
    private Short expand;
    @ApiModelProperty(value = "是否為葉子", example = "0/1", required = true)
    private Short isShow;
    @ApiModelProperty(value = "權限標識", example = "task.scheduled", required = true)
    private String permission;
    @ApiModelProperty(value = "備注", example = "備注", required = false)
    private String comt;
    @ApiModelProperty(value = "是否啟用", example = "1/0", required = false)
    private Short enable;
    @ApiModelProperty(value = "節點圖標CSS類名", example = "fa fas", required = false)
    private String iconcls;
    @ApiModelProperty(value = "請求地址", example = "app.syslog", required = false)
    private String request;
    @ApiModelProperty(value = "子部門", example = "父節點", required = false)
    private List children;

    @Override
    public Object getId() {
        return this.id;
    }

    @Override
    public void setId(Object id) {
        this.id = (String) id;
    }

    @Override
    public Object getParentId() {
        return this.parentId;
    }

    @Override
    public void setParentId(Object parentId) {
        this.parentId = (String) parentId;
    }

    @Override
    public String getName() {
        return this.menuName;
    }

    @Override
    public void setName(String name) {
        this.menuName = name;
    }

    @Override
    public List getChildren() {
        return this.children;
    }

    @Override
    public void setChildren(List children) {
        this.children = children;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public Short getMenuType() {
        return menuType;
    }

    public void setMenuType(Short menuType) {
        this.menuType = menuType;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public Long getSortNo() {
        return sortNo;
    }

    public void setSortNo(Long sortNo) {
        this.sortNo = sortNo;
    }

    public Short getExpand() {
        return expand;
    }

    public void setExpand(Short expand) {
        this.expand = expand;
    }

    public Short getIsShow() {
        return isShow;
    }

    public void setIsShow(Short isShow) {
        this.isShow = isShow;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }

    public String getComt() {
        return comt;
    }

    public void setComt(String comt) {
        this.comt = comt;
    }

    public Short getEnable() {
        return enable;
    }

    public void setEnable(Short enable) {
        this.enable = enable;
    }

    public String getIconcls() {
        return iconcls;
    }

    public void setIconcls(String iconcls) {
        this.iconcls = iconcls;
    }

    public String getRequest() {
        return request;
    }

    public void setRequest(String request) {
        this.request = request;
    }

    public String getMenuCode() {
        return menuCode;
    }

    public void setMenuCode(String menuCode) {
        this.menuCode = menuCode;
    }
}

  查詢出菜單對的所有數據,然後轉為樹結構即可 

     List dtoList = BeanMapper.mapList(menuList,MenuTreeDto.class);
        if(dtoList!=null && dtoList.size()>0) {
            TreeUtil treeUtil = new TreeUtil();
            List<MenuTreeDto> treeList = treeUtil.getChildTreeObjects(dtoList, parentId);
            return treeList;
        }

 

    生成樹的結構示例:菜單樹JSON

{ "success": true, "message": "請求成功", "data": [ { "id": "1", "menuName": "系統管理", "menuType": 1, "menuCode": "sys", "parentId": "0", "sortNo": 50, "expand": 0, "isShow": 1, "permission": "sys", "comt": "test", "enable": 1, "iconcls": "fa fa-angle-right", "request": "#", "children": [ { "id": "16", "menuName": "用戶角色", "menuType": 1, "menuCode": "user.role", "parentId": "1", "sortNo": 11, "expand": 0, "isShow": 0, "permission": "user.role", "comt": null, "enable": 1, "iconcls": "fa fa-users", "request": "app.sys.userroles", "children": null, "name": "用戶角色" }, { "id": "17", "menuName": "權限管理", "menuType": 1, "menuCode": "sys.access", "parentId": "1", "sortNo": 12, "expand": 0, "isShow": 1, "permission": "sys.access", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "app.sys.auth", "children": null, "name": "權限管理" }, { "id": "18", "menuName": "系統日志", "menuType": 1, "menuCode": "sys.syslog", "parentId": "1", "sortNo": 22, "expand": 1, "isShow": 1, "permission": "sys.syslog", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "app.syslog", "children": null, "name": "系統日志" }, { "id": "19", "menuName": "業務日志", "menuType": 1, "menuCode": "sys.log.business", "parentId": "1", "sortNo": 999, "expand": 1, "isShow": 1, "permission": "sys.log.business", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "app.businesslog", "children": null, "name": "業務日志" }, { "id": "2", "menuName": "用戶管理", "menuType": 1, "menuCode": "sys.user", "parentId": "1", "sortNo": 1, "expand": 0, "isShow": 1, "permission": "sys.user", "comt": null, "enable": 1, "iconcls": "fa fa-user", "request": "app.user", "children": null, "name": "用戶管理" }, { "id": "3", "menuName": "部門管理", "menuType": 1, "menuCode": "sys.dept", "parentId": "1", "sortNo": 2, "expand": 0, "isShow": 1, "permission": "sys.dept", "comt": null, "enable": 1, "iconcls": "fa fa-users", "request": "app.dept", "children": null, "name": "部門管理" }, { "id": "4", "menuName": "菜單管理", "menuType": 1, "menuCode": "sys.menu", "parentId": "1", "sortNo": 3, "expand": 0, "isShow": 1, "permission": "sys.menu", "comt": null, "enable": 1, "iconcls": "fa fa-bars", "request": "app.menu", "children": null, "name": "菜單管理" }, { "id": "5", "menuName": "角色管理", "menuType": 1, "menuCode": "sys.role", "parentId": "1", "sortNo": 4, "expand": 0, "isShow": 1, "permission": "sys.role", "comt": null, "enable": 1, "iconcls": "fa fa-cog", "request": "app.role", "children": null, "name": "角色管理" }, { "id": "6", "menuName": "會話管理", "menuType": 1, "menuCode": "sys.session", "parentId": "1", "sortNo": 6, "expand": 0, "isShow": 0, "permission": "sys.session", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "main.sys.session.list", "children": null, "name": "會話管理" }, { "id": "7", "menuName": "字典管理", "menuType": 1, "menuCode": "sys.dic", "parentId": "1", "sortNo": 7, "expand": 0, "isShow": 1, "permission": "sys.dic", "comt": null, "enable": 1, "iconcls": "fa fa-book", "request": "app.dictindex", "children": null, "name": "字典管理" }, { "id": "8", "menuName": "業務參數", "menuType": 1, "menuCode": "sys.param", "parentId": "1", "sortNo": 8, "expand": 0, "isShow": 0, "permission": "sys.param", "comt": null, "enable": 1, "iconcls": "fa fa-wrench", "request": "main.sys.param.list", "children": null, "name": "業務參數" }, { "id": "20", "menuName": "數據權限", "menuType": 1, "menuCode": "sys.dataauth", "parentId": "1", "sortNo": 20, "expand": 1, "isShow": 1, "permission": "sys.dataauth", "comt": null, "enable": 1, "iconcls": "fa fa-users", "request": "app.dataauth", "children": null, "name": "數據權限" } ], "name": "系統管理" }, { "id": "9", "menuName": "調度中心", "menuType": 1, "menuCode": "task", "parentId": "0", "sortNo": 2, "expand": 0, "isShow": 0, "permission": "task", "comt": null, "enable": 1, "iconcls": "fa fa-angle-right", "request": "#", "children": [ { "id": "10", "menuName": "任務組管理", "menuType": 1, "menuCode": "task.group", "parentId": "9", "sortNo": 1, "expand": 0, "isShow": 0, "permission": "task.group", "comt": null, "enable": 1, "iconcls": "fa fa-tasks", "request": "main.task.group.list", "children": null, "name": "任務組管理" }, { "id": "11", "menuName": "任務管理", "menuType": 1, "menuCode": "task.scheduler", "parentId": "9", "sortNo": 2, "expand": 0, "isShow": 0, "permission": "task.scheduler", "comt": null, "enable": 1, "iconcls": "fa fa-table", "request": "main.task.scheduler.list", "children": null, "name": "任務管理" }, { "id": "12", "menuName": "調度管理", "menuType": 1, "menuCode": "task.scheduled", "parentId": "9", "sortNo": 3, "expand": 0, "isShow": 0, "permission": "task.scheduled", "comt": null, "enable": 1, "iconcls": "fa fa-user", "request": "main.task.scheduled.list", "children": null, "name": "調度管理" }, { "id": "13", "menuName": "調度日志", "menuType": 1, "menuCode": "task.log", "parentId": "9", "sortNo": 4, "expand": 0, "isShow": 0, "permission": "task.log", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "main.task.log.list", "children": null, "name": "調度日志" }, { "id": "15", "menuName": "角色權限", "menuType": 1, "menuCode": "role.access", "parentId": "9", "sortNo": 11, "expand": 1, "isShow": 1, "permission": "role.access", "comt": null, "enable": 1, "iconcls": "fa fa-list", "request": "app.sys.roleaccess", "children": null, "name": "角色權限" } ], "name": "調度中心" } ] } View Code

   至此,可以方便實現樹結構JSON的返回。over.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved