java返回树结构工具类

代码:

package com.ruoyi.common.utils;


import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 介绍:生成树形结构
 * // 抽取方法的时候要考虑一个问题,即,返回一个集合,集合中有父节点和字节点,父节点和字节点的类型一定要统一,
 * // 即这里返回的是一个装有TreeUtils类型的集合,那么集合里的父节点和子节点一定都得是TreeUtils类型的
 */
public class TreeUtils<T> {
    private String id;           // 节点id
    private String parentId;    // 父节点
    private String label;         // 节点名称 ,返回给前台的是一个装有TreeUtils的集合的数据,所以在前台显示数据的时候,el-tree的lable的名字的和这个一样
    private List<TreeUtils> children;  // 父节点中存放子节点的集合
    private T data;              //  节点数据

    public String getId() {
        return id;
    }

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

    public String getParentId() {
        return parentId;
    }

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

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public List<TreeUtils> getChildren() {
        return children;
    }

    public void setChildren(List<TreeUtils> children) {
        this.children = children;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    /**
     * @param listData   // 从数据库中查询的数据
     * @return
     */
    public static List<TreeUtils> getTreeList(List<?> listData ,String id,String parentId,String categoryName) throws Exception{

        List<TreeUtils> resultList = new ArrayList<TreeUtils>();  // 最终返回的结果
        Map<String ,Object> map = new HashMap<String,Object>();

        for(int i =0;i<listData.size() && !listData.isEmpty();i++){

            // 写一个与该方法差不多的方法,将得到TreeUtils的代码抽取出来
            // 也可以将listData集合整个转换成装有TreeUtils的集合x,然后再循环x
            TreeUtils treeUtils = new TreeUtils();
            treeUtils.setId(TreeUtils.getFileValue(listData.get(i),id).toString()); // id              // 返回值为Object无法直接转换成Integer,先toString,再转换成Integer。这里的返回值写成Object是因为多种类型字段的值都可以用该方法
            treeUtils.setParentId(TreeUtils.getFileValue(listData.get(i),parentId).toString()); // 父id
            treeUtils.setLabel(TreeUtils.getFileValue(listData.get(i),categoryName).toString());  // 节点名
            //System.out.println("节点名为+"+TreeUtils.getFileValue(listData.get(i),categoryName).toString());
            treeUtils.setData(listData.get(i));   // data:原对象中的所有属性,无children

            // 通过反射得到每条数据的id将数据封装的map集合中,id为键,元素本身为值
            map.put(treeUtils.getId(),treeUtils);


            // 将所有顶层元素添加到resultList集合中
            //if( 0 == treeUtils.getParentId()){
            //   resultList.add(treeUtils);
            // }
        }
        // 得到所有的顶层节点,游离节点也算作顶层节点
        // 优点一,不用知道等级节点的id
        // 优点而,只查询了一次数据库
        for(int i =0;i<listData.size();i++){
            if(!map.containsKey(TreeUtils.getFileValue(listData.get(i),parentId).toString())){
                resultList.add((TreeUtils) map.get(TreeUtils.getFileValue(listData.get(i),id).toString()));
            }
        }



        for(int i =0;i<listData.size() && !listData.isEmpty();i++){
            TreeUtils obj = (TreeUtils)map.get(TreeUtils.getFileValue(listData.get(i), parentId).toString());
            if(obj != null){
                if(obj.getChildren() == null){
                    obj.setChildren(new ArrayList());
                }
                obj.getChildren().add(map.get(TreeUtils.getFileValue(listData.get(i),id).toString()));
            }
        }
        return resultList;
    }
    /**
     * 通过反射得到的数据类型的也是不一定的,所以这里我们返回值为Object
     * Object是无法直接转为Integer,现将Object转为String,然后再将String转为Integer
     * @param item
     * @param fileName
     * @return
     */
    public static Object  getFileValue(Object item,String fileName) throws Exception {
        Class<?> aClass = item.getClass();
        Field file = aClass.getDeclaredField(fileName); // 得到所有字段包括私有字段
        file.setAccessible(true); // 取消访问限制
        return file.get(item);    // 这里就体现出反射的意思了,我们通常都是通过对象拿到字段,这里是通过字段,将类的字节码对象为参数传入,来得到值
    }

}
package com.ruoyi.common.utils;


import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 介绍:生成树形结构
 * // 抽取方法的时候要考虑一个问题,即,返回一个集合,集合中有父节点和字节点,父节点和字节点的类型一定要统一,
 * // 即这里返回的是一个装有TreeUtils类型的集合,那么集合里的父节点和子节点一定都得是TreeUtils类型的
 */
public class TreeUtils<T> {
    private String id;           // 节点id
    private String parentId;    // 父节点
    private String label;         // 节点名称 ,返回给前台的是一个装有TreeUtils的集合的数据,所以在前台显示数据的时候,el-tree的lable的名字的和这个一样
    private List<TreeUtils> children;  // 父节点中存放子节点的集合
    private T data;              //  节点数据

    public String getId() {
        return id;
    }

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

    public String getParentId() {
        return parentId;
    }

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

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public List<TreeUtils> getChildren() {
        return children;
    }

    public void setChildren(List<TreeUtils> children) {
        this.children = children;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    /**
     * @param listData   // 从数据库中查询的数据
     * @return
     */
    public static List<TreeUtils> getTreeList(List<?> listData ,String id,String parentId,String categoryName) throws Exception{

        List<TreeUtils> resultList = new ArrayList<TreeUtils>();  // 最终返回的结果
        Map<String ,Object> map = new HashMap<String,Object>();

        for(int i =0;i<listData.size() && !listData.isEmpty();i++){

            // 写一个与该方法差不多的方法,将得到TreeUtils的代码抽取出来
            // 也可以将listData集合整个转换成装有TreeUtils的集合x,然后再循环x
            TreeUtils treeUtils = new TreeUtils();
            treeUtils.setId(TreeUtils.getFileValue(listData.get(i),id).toString()); // id              // 返回值为Object无法直接转换成Integer,先toString,再转换成Integer。这里的返回值写成Object是因为多种类型字段的值都可以用该方法
            treeUtils.setParentId(TreeUtils.getFileValue(listData.get(i),parentId).toString()); // 父id
            treeUtils.setLabel(TreeUtils.getFileValue(listData.get(i),categoryName).toString());  // 节点名
            //System.out.println("节点名为+"+TreeUtils.getFileValue(listData.get(i),categoryName).toString());
            treeUtils.setData(listData.get(i));   // data:原对象中的所有属性,无children

            // 通过反射得到每条数据的id将数据封装的map集合中,id为键,元素本身为值
            map.put(treeUtils.getId(),treeUtils);


            // 将所有顶层元素添加到resultList集合中
            //if( 0 == treeUtils.getParentId()){
            //   resultList.add(treeUtils);
            // }
        }
        // 得到所有的顶层节点,游离节点也算作顶层节点
        // 优点一,不用知道等级节点的id
        // 优点而,只查询了一次数据库
        for(int i =0;i<listData.size();i++){
            if(!map.containsKey(TreeUtils.getFileValue(listData.get(i),parentId).toString())){
                resultList.add((TreeUtils) map.get(TreeUtils.getFileValue(listData.get(i),id).toString()));
            }
        }



        for(int i =0;i<listData.size() && !listData.isEmpty();i++){
            TreeUtils obj = (TreeUtils)map.get(TreeUtils.getFileValue(listData.get(i), parentId).toString());
            if(obj != null){
                if(obj.getChildren() == null){
                    obj.setChildren(new ArrayList());
                }
                obj.getChildren().add(map.get(TreeUtils.getFileValue(listData.get(i),id).toString()));
            }
        }
        return resultList;
    }
    /**
     * 通过反射得到的数据类型的也是不一定的,所以这里我们返回值为Object
     * Object是无法直接转为Integer,现将Object转为String,然后再将String转为Integer
     * @param item
     * @param fileName
     * @return
     */
    public static Object  getFileValue(Object item,String fileName) throws Exception {
        Class<?> aClass = item.getClass();
        Field file = aClass.getDeclaredField(fileName); // 得到所有字段包括私有字段
        file.setAccessible(true); // 取消访问限制
        return file.get(item);    // 这里就体现出反射的意思了,我们通常都是通过对象拿到字段,这里是通过字段,将类的字节码对象为参数传入,来得到值
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值