一個樹型通用接口


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

  它們有共同的屬性: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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM