树形结构工具(JAVA)Tree, TreeBean

 树形工具构建,java实现

package com.tansun.risk.rwa.common.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 树形结构工具类
 *
 * @author IT_CREATE
 * @date 2023/12/13 16:59
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class TreeBean<idType extends Comparable<idType>> implements Serializable {
    private static final long serialVersionUID = 2978205537968679584L;

    /*id和pid必须赋值,otherParameter装一些其他参数,比如name,key-value键值对的形式*/
    /*将你从数据库查出来的集合循环,然后对每一行数据进行赋值转换成TreeBean结构,调用内部静态方法即可得到树形结构列表*/

    /**
     * id
     */
    private idType id;

    /**
     * pid
     */
    private idType pid;

    /**
     * 其他参数,需要展示的参数,比如name之类的
     */
    private Map<String, Object> otherParameter;


    /*---------------------------------下面这些不需要你赋值-------------------------------------------*/

    /**
     * 是否含有下一级
     */
    private Boolean hasChildren;

    /**
     * 包含的子节点
     */
    private List<TreeBean<idType>> children;

    /**
     * 子节点的集合大小
     */
    private Long childrenSize;

    /**
     * 级别
     */
    private Long level;

    /**
     * 使用递归方法建树(返回包含顶级节点)
     *
     * @param treeBeans 按规则转换的树形实体集合列表,没有层次结构
     * @param topId     指定顶级节点id,必须指定
     * @return 树形结构实体集合
     */
    public static <idType extends Comparable<idType>> List<TreeBean<idType>> buildByRecursive(List<TreeBean<idType>> treeBeans, idType topId) {
        return buildByRecursive(treeBeans, topId, true);
    }

    /**
     * 使用递归方法建树
     *
     * @param treeBeans      按规则转换的树形实体集合列表,没有层次结构
     * @param topId          指定顶级节点id,必须指定
     * @param isCarryTopNode 返回节点层次结构,是否携带顶级节点返回
     *                       <br/>设置为false,则将顶级节点的数据去除,返回指定顶级节点的子节点树形结构集合;
     *                       <br/>设置为true,则返回包含顶级节点的树形结构集合(则返回集合中只包含一个顶级节点,顶级节点内部包含子节点信息)
     * @return 树形结构实体集合
     */
    public static <idType extends Comparable<idType>> List<TreeBean<idType>> buildByRecursive(List<TreeBean<idType>> treeBeans, idType topId, boolean isCarryTopNode) {
        List<TreeBean<idType>> trees = new ArrayList<>();
        TreeBean<idType> treeBeanTop = null;
        // 循环节点集合,从顶级节点得二级节点开始层层递归
        for (TreeBean<idType> treeBean : treeBeans) {
            // 如果节点得父id是顶级节点,则进入查找子节点迭代,层层查找
            // 如果父节点不是顶级节点,则忽略掉
            if (treeBean.getPid().compareTo(topId) == 0) {
                Long level = 1L;
                // 如果需要将顶级节点返回,则除开顶级节点以下的节点则从2级开始表示,如果不反回顶级节点,则从1级开始表示
                if (isCarryTopNode) {
                    level = 2L;
                }
                TreeBean<idType> treeBean2 = findChildren(treeBean, treeBeans, level);
                if (CollectionUtils.isEmpty(treeBean2.getChildren())) {
                    treeBean2.setHasChildren(false);
                    treeBean2.setChildrenSize(0L);
                    treeBean2.setLevel(level);
                } else {
                    treeBean2.setHasChildren(true);
                    treeBean2.setLevel(level);
                    treeBean2.setChildrenSize((long) treeBean2.getChildren().size());
                }
                trees.add(treeBean2);
            } else if (isCarryTopNode && 0 == treeBean.getId().compareTo(topId)) {
                // 记录集合中得顶级节点
                treeBeanTop = treeBean;
            }
        }
        if (!ObjectUtils.isEmpty(treeBeanTop)) {
            treeBeanTop.setChildren(trees)
                    .setChildrenSize((long) trees.size())
                    .setHasChildren(true)
                    .setLevel(1L);
            trees = new ArrayList<>();
            trees.add(treeBeanTop);
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeBean  当前节点
     * @param treeBeans 所有节点
     * @param level     当前节点的层次
     * @return 树形结构实体
     */
    private static <idType extends Comparable<idType>> TreeBean<idType> findChildren(TreeBean<idType> treeBean, List<TreeBean<idType>> treeBeans, Long level) {
        for (TreeBean<idType> it : treeBeans) {
            if (0 == treeBean.getId().compareTo(it.getPid())) {
                if (treeBean.getChildren() == null) {
                    treeBean.setChildren(new ArrayList<>());
                }
                TreeBean<idType> treeBean2 = findChildren(it, treeBeans, level + 1);
                if (!CollectionUtils.isEmpty(treeBean2.getChildren())) {
                    treeBean2.setHasChildren(true);
                    treeBean2.setChildrenSize((long) treeBean.getChildren().size());
                    treeBean2.setLevel(level + 1);
                } else {
                    treeBean2.setHasChildren(false);
                    treeBean2.setChildrenSize(0L);
                    treeBean2.setLevel(level + 1);
                }
                treeBean.getChildren().add(treeBean2);
            }
        }
        return treeBean;
    }

    /**
     * 根据节点ID获取所有父节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param id        节点Id
     * @return 所有父节点(从最底层到最顶层顺序返回的集合,如果需要正序,请自行将集合进行反转即可)
     */
    public static <idType extends Comparable<idType>> List<TreeBean<idType>> getAllParentNode(List<TreeBean<idType>> treeBeans, idType id) {
        List<TreeBean<idType>> data = new ArrayList<>();
        return allParentNodeIteration(data, treeBeans, id);
    }

    private static <idType extends Comparable<idType>> List<TreeBean<idType>> allParentNodeIteration(List<TreeBean<idType>> data, List<TreeBean<idType>> treeBeans, idType id) {
        TreeBean<idType> it = getParentNode(treeBeans, id);
        if (it != null) {
            data.add(it);
            return allParentNodeIteration(data, treeBeans, it.getPid());
        }
        return data;
    }

    /**
     * 根据节点ID获取父节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param id        节点Id
     * @return 其父节点
     */
    public static <idType extends Comparable<idType>> TreeBean<idType> getParentNode(List<TreeBean<idType>> treeBeans, idType id) {
        TreeBean<idType> it = getNode(treeBeans, id);
        if (it != null) {
            return getNode(treeBeans, it.getPid());
        } else {
            return null;
        }
    }

    /**
     * 根据节点ID获取节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param id        节点Id
     * @return 节点
     */
    public static <idType extends Comparable<idType>> TreeBean<idType> getNode(List<TreeBean<idType>> treeBeans, idType id) {
        for (TreeBean<idType> treeBean : treeBeans) {
            if (treeBean.getId().compareTo(id) == 0) {
                return treeBean;
            } else if (!CollectionUtils.isEmpty(treeBean.getChildren())) {
                TreeBean<idType> node = getNode(treeBean.getChildren(), id);
                if (node != null) {
                    return node;
                }
            }
        }
        return null;
    }

    /**
     * 根据节点ID移出节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param id        节点Id
     */
    public static <idType extends Comparable<idType>> void removeNode(List<TreeBean<idType>> treeBeans, idType id) {
        removeNode(null, treeBeans, id);
    }

    private static <idType extends Comparable<idType>> void removeNode(TreeBean<idType> parentNode, List<TreeBean<idType>> treeBeans, idType id) {
        Iterator<TreeBean<idType>> iterator = treeBeans.iterator();
        while (iterator.hasNext()) {
            TreeBean<idType> next = iterator.next();
            if (next.getId().compareTo(id) == 0) {
                iterator.remove();
                if (parentNode != null) {
                    parentNode.setHasChildren(!CollectionUtils.isEmpty(parentNode.getChildren()));
                    parentNode.setChildrenSize(CollectionUtils.isEmpty(parentNode.getChildren()) ? 0 : (long) parentNode.getChildren().size());
                }
                return;
            } else if (!CollectionUtils.isEmpty(next.getChildren())) {
                removeNode(next, next.getChildren(), id);
            }
        }
    }

    /**
     * 根据节点ID更新节点参数Prams
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param node      节点
     */
    public static <idType extends Comparable<idType>> void updateNodeParams(List<TreeBean<idType>> treeBeans, TreeBean<idType> node) {
        for (TreeBean<idType> treeBean : treeBeans) {
            if (treeBean.getId().compareTo(node.getId()) == 0) {
                treeBean.setOtherParameter(node.getOtherParameter());
                return;
            } else if (!CollectionUtils.isEmpty(treeBean.getChildren())) {
                updateNodeParams(treeBean.getChildren(), node);
            }
        }
    }

    /**
     * 根据节点替换相同ID的节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param node      节点
     */
    public static <idType extends Comparable<idType>> void replaceNode(List<TreeBean<idType>> treeBeans, TreeBean<idType> node) {
        for (int i = 0; i < treeBeans.size(); i++) {
            TreeBean<idType> treeBean = treeBeans.get(i);
            if (treeBean.getId().compareTo(node.getId()) == 0) {
                node.setLevel(treeBean.getLevel());
                node.setHasChildren(!CollectionUtils.isEmpty(node.getChildren()));
                node.setChildrenSize(CollectionUtils.isEmpty(node.getChildren()) ? 0 : (long) node.getChildren().size());
                treeBeans.set(i, node);
                return;
            } else if (!CollectionUtils.isEmpty(treeBean.getChildren())) {
                replaceNode(treeBean.getChildren(), node);
            }
        }
    }

    /**
     * 添加节点,根据节点指定的pid添加到对应的父节点下
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param node      节点
     */
    public static <idType extends Comparable<idType>> void addNode(List<TreeBean<idType>> treeBeans, TreeBean<idType> node) {
        for (TreeBean<idType> treeBean : treeBeans) {
            if (treeBean.getId().compareTo(node.getPid()) == 0) {
                if (treeBean.getChildren() == null) {
                    treeBean.setChildren(new ArrayList<>());
                }
                node.setLevel(treeBean.getLevel() + 1);
                node.setHasChildren(!CollectionUtils.isEmpty(node.getChildren()));
                node.setChildrenSize(CollectionUtils.isEmpty(node.getChildren()) ? 0 : (long) node.getChildren().size());
                treeBean.getChildren().add(node);
                treeBean.setHasChildren(true);
                treeBean.setChildrenSize((long) treeBean.getChildren().size());
                return;
            } else if (!CollectionUtils.isEmpty(treeBean.getChildren())) {
                addNode(treeBean.getChildren(), node);
            }
        }
    }

    /**
     * 迭代树形结构,再每个节点上执行回调,回调会传入当前节点
     *
     * @param treeBeans 构建好的树形结构(包含一个顶级节点的集合)
     * @param callback  回调函数 function(node){}
     */
    public static <idType extends Comparable<idType>> void iteration(List<TreeBean<idType>> treeBeans, Action1<TreeBean<idType>> callback) {
        for (TreeBean<idType> treeBean : treeBeans) {
            if (callback != null) {
                callback.call(treeBean);
            }
            if (!CollectionUtils.isEmpty(treeBean.getChildren())) {
                iteration(treeBean.getChildren(), callback);
            }
        }
    }

    /**
     * 接口
     *
     * @param <T> 泛型
     */
    public interface Action1<T> {
        /**
         * 回调方法
         *
         * @param t 入参对象
         * @throws RuntimeException 运行时异常
         */
        void call(T t) throws RuntimeException;
    }
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的 Java 工具类,可以将 List 转换为树形结构: ```java import java.util.*; public class TreeUtil { public static <T extends TreeNode> List<T> buildTree(List<T> nodes) { if (nodes == null || nodes.size() == 0) { return Collections.emptyList(); } Map<Long, T> nodeMap = new HashMap<>(); for (T node : nodes) { nodeMap.put(node.getId(), node); } List<T> rootNodes = new ArrayList<>(); for (T node : nodes) { T parent = nodeMap.get(node.getParentId()); if (parent != null) { parent.addChild(node); } else { rootNodes.add(node); } } return rootNodes; } public interface TreeNode { Long getId(); Long getParentId(); void addChild(TreeNode child); List<? extends TreeNode> getChildren(); } } ``` 这个工具类包含了一个通用的接口 `TreeNode`,通过实现这个接口,可以将任意类型的 List 转换为树形结构。 `TreeNode` 接口包含了三个方法: - `getId()`:获取节点的唯一标识符。 - `getParentId()`:获取节点的父节点标识符。 - `addChild(TreeNode child)`:将一个子节点添加到当前节点。 - `getChildren()`:获取当前节点的所有子节点。 使用这个工具类非常简单,只需要将需要转换的 List 传入 `buildTree()` 方法中即可: ```java List<MyNode> nodes = ...; // 获取需要转换的 List List<MyNode> rootNodes = TreeUtil.buildTree(nodes); ``` 其中 `MyNode` 是一个实现了 `TreeNode` 接口的自定义类。注意,为了能够正确地构建树形结构,每个节点的 `getParentId()` 方法必须返回其父节点的 `getId()` 值。否则,节点将无法正确地添加到树中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值