你的位置:首页 > 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.