栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java之TreeUtils生成一切对象树形结构案例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java之TreeUtils生成一切对象树形结构案例

项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现。

TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口。

 
  public interface TreeNode {
    
    T id();
    
    T parentId();
    
    boolean root();
    
    void setChildren(List> children);
    
    List> getChildren();
  }

TreeUtils用来生成树形结构,以及获取所有叶子节点等操作


public class TreeUtils {
  
  public static > List generateTrees(List nodes) {
    List roots = new ArrayList<>();
    for (Iterator ite = nodes.iterator(); ite.hasNext(); ) {
      T node = ite.next();
      if (node.root()) {
 roots.add(node);
 // 从所有节点列表中删除该节点,以免后续重复遍历该节点
 ite.remove();
      }
    }
    roots.forEach(r -> {
      setChildren(r, nodes);
    });
    return roots;
  }
  
  @SuppressWarnings("all")
  public static  void setChildren(T parent, List nodes) {
    List children = new ArrayList<>();
    Object parentId = parent.id();
    for (Iterator ite = nodes.iterator(); ite.hasNext(); ) {
      T node = ite.next();
      if (Objects.equals(node.parentId(), parentId)) {
 children.add(node);
 // 从所有节点列表中删除该节点,以免后续重复遍历该节点
 ite.remove();
      }
    }
    // 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子
    if (children.isEmpty()) {
      return;
    }
    parent.setChildren(children);
    children.forEach(m -> {
      // 递归设置子节点
      setChildren(m, nodes);
    });
  }
  
  public static > List getLeafs(T parent) {
    List leafs = new ArrayList<>();
    fillLeaf(parent, leafs);
    return leafs;
  }
  
  @SuppressWarnings("all")
  public static  void fillLeaf(T parent, List leafs) {
    List children = parent.getChildren();
    // 如果节点没有子节点则说明为叶子节点
    if (CollectionUtils.isEmpty(children)) {
      leafs.add(parent);
      return;
    }
    // 递归调用子节点,查找叶子节点
    for (T child : children) {
      fillLeaf(child, leafs);
    }
  }
}

具体使用方式之声明树节点对象

@Getter
@Setter
public class ResourceListVO implements TreeNode {
  private Long id;
  private Long pid;
  private Integer type;
  private String name;
  private String icon;
  private String code;
  private Integer status;
  private List children;
  @Override
  public Long id() {
    return this.id;
  }
  @Override
  public Long parentId() {
    return this.pid;
  }
  @Override
  public boolean root() {
    return Objects.equals(this.pid, 0L);
  }
  @Override
  public void setChildren(List children) {
    this.children = children;
  }
}

具体使用方式之调用

 
  public List listByAccountId(Long accountId) {
    return TreeUtils.generateTrees(BeanUtils.copyProperties(mapper.selectByAccountId(userId), ResourceListVO.class));
  }

通过使用TreeUtils工具可以统一方便地生成一切对象的树形结构以及其他一些对树的操作,避免对每个对象都用特定代码生成。使用起来就是几个字简洁方便爽歪歪biu特否。

补充知识:TreeUtil 数据库菜单生成无限级树形结构

1、项目需求:

从数据库从加载所有的菜单出来,菜单中有

id,parentId,name字段

希望能有一个工具帮我进行树形结构重组;

实例类:

package com.lming.chcservice.util; 
import lombok.Data; 
import java.util.List;
@Data
public class TreeNode {
  
  private String id;
  
  private String parentId;
  
  private String name;
  
  private boolean hasChild;
 
  public TreeNode(String id, String parentId, String name) {
    this.id = id;
    this.parentId = parentId;
    this.name = name;
  }
}

工具类:

package com.lming.chcservice.util;
 
import java.util.ArrayList;
import java.util.linkedHashMap;
import java.util.List;
import java.util.Map;
 

public class TreeUtil { 
 
  public static Map mapArray = new linkedHashMap(); 
  public List menuCommon;
  public List list = new ArrayList();
 
  public List treeMenu(List menu){
    this.menuCommon = menu;
    for (TreeNode treeNode : menu) {
      Map mapArr = new linkedHashMap();
      if(treeNode.getParentId().equals("0")){
 setTreeMap(mapArr,treeNode);
 list.add(mapArr);
      }
    }
    return list;
  }
 
  public List menuChild(String id){
    List lists = new ArrayList();
    for(TreeNode a:menuCommon){
      Map childArray = new linkedHashMap();
      if(a.getParentId() .equals(id)){
 setTreeMap(childArray,a);
 lists.add(childArray);
      }
    }
    return lists;
  }
 
  private void setTreeMap(Map mapArr,TreeNode treeNode){
    mapArr.put("id", treeNode.getId());
    mapArr.put("name", treeNode.getName());
    mapArr.put("parentId", treeNode.getParentId());
    List childrens = menuChild(treeNode.getId());
    if(childrens.size()>0){
      mapArr.put("hasChild",true);
    }
    else{
      mapArr.put("hasChildren",false);
    }
    mapArr.put("childrens", menuChild(treeNode.getId()));
  }
 
  public static void main(String[] args){
 
    List treeNodeList = new ArrayList<>();
    TreeNode treeNode1 = new TreeNode("1","0","首页");
    TreeNode treeNode2 = new TreeNode("2","0","订单");
    TreeNode treeNode3 = new TreeNode("3","1","预约");
    TreeNode treeNode4 = new TreeNode("4","2","捐献");
    TreeNode treeNode5 = new TreeNode("5","4","我的订单");
    TreeNode treeNode6 = new TreeNode("6","5","个人中心");
    TreeNode treeNode7 = new TreeNode("7","6","个人中心2");
    TreeNode treeNode8 = new TreeNode("8","99","个人中心3");
    treeNodeList.add(treeNode1);
    treeNodeList.add(treeNode6);
    treeNodeList.add(treeNode5);
    treeNodeList.add(treeNode3);
    treeNodeList.add(treeNode4);
    treeNodeList.add(treeNode2);
    treeNodeList.add(treeNode7);
    treeNodeList.add(treeNode8); 
 
    TreeUtil treeUtil = new TreeUtil();
    System.out.print(JsonUtil.toJson(treeUtil.treeMenu(treeNodeList))); 
  } 
}


测试结果:

[
 {
  "id": "1",
  "name": "首页",
  "parentId": "0",
  "hasChild": true,
  "childrens": [
   {
    "id": "3",
    "name": "预约",
    "parentId": "1",
    "hasChildren": false,
    "childrens": []
   }
  ]
 },
 {
  "id": "2",
  "name": "订单",
  "parentId": "0",
  "hasChild": true,
  "childrens": [
   {
    "id": "4",
    "name": "捐献",
    "parentId": "2",
    "hasChild": true,
    "childrens": [
     {
      "id": "5",
      "name": "我的订单",
      "parentId": "4",
      "hasChild": true,
      "childrens": [
{
 "id": "6",
 "name": "个人中心",
 "parentId": "5",
 "hasChild": true,
 "childrens": [
  {
   "id": "7",
   "name": "个人中心2",
   "parentId": "6",
   "hasChildren": false,
   "childrens": []
  }
 ]
}
      ]
     }
    ]
   }
  ]
 }
]

实力类不一致怎么办? 自己写一个实体转换类,将类的对象属性转换成上面的实体类,然后在调用,当然最快的方式直接修改实体类即可用。

以上这篇java之TreeUtils生成一切对象树形结构案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号