【JAVA 系列】树形公用泛型类

一、公用泛型类

package com.sxwh.common.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
 **构建树的类
 */
public class TreeBuilder<T> {
    
     /**
     * 将数据列表中的每个元素转换为另一种类型的对象,并且根据字段映射关系填充相应字段的值。
     * Describe:返回所需的第一级List,第二级List,第三级List,等等级
     * parameter: resultMapper 默认构造函数创建对象
     * fieldMappers 字段映射
     * dataList     查询到的数据
     * SkillDescription:Supplier 是一个功能接口,代表结果的提供者,在这里其实就相当于默认构造函数创建的对象;具体信息可自行查阅
     */
 public <T, R> List<R> buildTree(List<T> dataList, Map<String, String> fieldMappers, Supplier<R> resultMapper) {
         * */
        List<R> nodeList = dataList.stream()
                .map(data -> {
                    //获取一个结果对象的实例
                    R result = resultMapper.get();
                    fieldMappers.forEach((fieldName, mapper) -> {
                        String fieldValue = String.valueOf(BeanUtil.getFieldValue(data, mapper));
                        BeanUtil.setFieldValue(result, fieldName, fieldValue);
                    });
                    return result;
                })
                .distinct()
                .collect(Collectors.toList());
        return nodeList;
    }

    /**
     * 递归实现
     */
    public void recursionFn(List<T> oneList, List<T> twoList, List<T> threeList, T t) {
        List<T> childList = getChildList(xlList, pmList, fdList, t);
        //如果要循环的list为空,则截止到上一层,例如:第三级传入null,则只能循环到第二级list
        if (ObjectUtil.isNotEmpty(childList)) {
            // 使用反射调用setChildren方法
            try {
                Method setChildrenMethod = t.getClass().getMethod("setChildren", List.class);
                setChildrenMethod.invoke(t, childList);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                // 处理异常
                throw new RuntimeException("当前传入类对象没有Children字段,请检查!");
            }
            childList.forEach(child -> {
                try {
                    recursionFn(xlList, pmList, fdList, child);
                } catch (Exception e) {
                    throw new RuntimeException("递归异常");
                }
            });
        }
    }

    /**
     * 获取子节点
     */
    public List<T> getChildList(List<T> xlList, List<T> pmList, List<T> fdList, T t) {
        List<T> tlist = new ArrayList<>();
        String Code = getCityCode(t);
        int codeLen = Code.length();
        // 根据节点类型决定要遍历的列表
        List<T> forlist = getObjectListByCodeLength(xlList, pmList, fdList, codeLen);
        if (ObjectUtil.isNotEmpty(forlist)) {
            for (T n : forlist) {
                // 根据具体业务逻辑筛选子节点
                if (isChildNode(n, Code)) {
                    tlist.add(n);
                }
            }
            return tlist;
        } else {
            return forlist;
        }

    }

    /**
     * 根据编号长度决定要遍历的列表
     */
    private List<T> getObjectListByCodeLength(List<T> xlList, List<T> pmList, List<T> fdList, int codeLen) {
        if (codeLen == 2) {
            return xlList;
        } else if (codeLen == 4) {
            return pmList;
        } else if (codeLen == 6) {
            return fdList;
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 获取节点的编号
     */
    private String getCityCode(T t) {
        String CodeValue = (String) BeanUtil.getFieldValue(t, "code");
        if (CodeValue != null) {
            return CodeValue.toString();
        } else {
            throw new RuntimeException("获取节点代码值为空");
        }
    }

    /**
     * 判断节点是否为目标节点的子节点
     */
    private boolean isChildNode(T node, String parentCityCode) {
        String Code = null;
        Code = getCityCode(node);
        if (ObjectUtil.equals(Code.substring(0, Code.length() - 2), parentCityCode)) {
            return true;
        }
        return false;
    }
}

二、实体类

public class Node {
    // 节点的属性和方法
    private String code;
    private String name;
   /**
     * 子节点
     */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<Node> children;
    public Node(Node  node) {
      this.name= node.getName();
      this.code= node.getCode();
      this.children= node.getChildren().stream().map(Node::new).collect(Collectors.toList());
    }
}

三 、数据类

 public class testModel {
    private String oneCode;
    private String oneName;
    private String twoCode;
    private String twoName;
    private String threeCode;
    private String threeName;
}
 // 构造方法
    public testModel (testModel model) {
        this.oneCode=model.getOneCode();
        this.oneName=model.getOneName() ;
        this.twoCode= model.gettwoCode();
        this.twoName= model.gettwoName();
        this.threeCode= model.getthreeCode();
        this.threeName=model.get threeName();
    }

四、调用方法

     // 创建列表
      List<testModel > datalist= new ArrayList<>();
     //添加数据
 datalist.add(new CityData("02","第一级",  "0202", "第二级",  "020205", "第三级",
                "02020501","第四级");
 
   //构建所需的list
   TreeBuilder<Node> treeBuilder = new TreeBuilder<>();
        Map<String, String> dlFieldMappers = Map.of("code", "oneCode", "name", "oneName");
        Map<String, String> xlFieldMappers = Map.of("code", "twoCode", "name", "twoName");
        Map<String, String> pmFieldMappers = Map.of("code", "threeCode", "name", "threeName");
    //能创建对象实例工厂
        Supplier<Node> nodeSupplier =Node::new;
    
        List<Node> oneList = treeBuilder.buildTree(datalist, dlFieldMappers, nodeSupplier );
        List<Node> twoList = treeBuilder.buildTree(datalist, xlFieldMappers, nodeSupplier );
        List<Node> threeList = treeBuilder.buildTree(datalist, pmFieldMappers, nodeSupplier );

/   /总list
        List<Node> Nodes = new ArrayList<>();
        Nodes.addAll(oneList );
        Nodes.addAll(twoList );
        Nodes.addAll(threeList );
        //返回的list
        List<Node> list = new ArrayList<>();
        for (Node  item: oneList ) {
            treeBuilder.recursionFn(twoList , threeList , null, item);
            list.add(item);
        }
        if (list.isEmpty()) {
            list = Nodes;
        }
        List<Node> treeNode = list.stream().map(Node::new).collect(Collectors.toList());
        return treeNode;
  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的炸串拌饼店

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值