JAVA通用类型的树结构转换工具

import java.util.List;
/**
 * @Description  泛型接口
 * `T`:通常用来表示节点的标识符(ID)的类型。例如,如果树中的每个节点都有一个唯一的整数ID,那么 `T` 可能是 `Integer` 类型。
 * `K`:通常用来表示节点的子节点类型。
 *  在一个典型的树结构中,子节点也是树节点的类型,因此 `K` 通常与 `TreeNode<T, K>` 本身类型相同,但也可以是任何其他类型。
 */
public interface TreeNode<T,K> {

    T getParentID();

    T getId();

    List<K> getChildren();

    void setChildren(List<K> list);
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description 树状结构生成工具类
 * <p>
 */
public class TreeUtil {
    private TreeUtil() {
    }

    public static <T extends TreeNode> List<T> toObjTree(Collection<T> list) {
        List<T> result = Lists.newArrayList();
        Map<Object,T> map = list.stream().collect(Collectors.toMap(T::getId,Function.identity()));
        list.forEach(t->{
            if(map.containsKey(t.getPid())){
                if(map.get(t.getParentID()).getChildren()==null){
                    map.get(t.getParentID()).setChildren(Lists.newArrayList());
                }
                map.get(t.getParentID()).getChildren().add(t);
            }else {
                result.add(t);
            }
        });
        return  result;
    }



    public static <T extends TreeNode> JSONArray toTree(Collection<T> list) {
        return toTree(list, "id", "parentID", "children");
    }

    public static <T extends TreeNode> JSONArray toTree(Collection<T> list, String id, String parentID, String children) {
        return listToTree(JSONArray.parseArray(JSON.toJSONString(list)), id, parentID, children);
    }

    public static <PlainArea> JSONArray toTreeArea(Collection<PlainArea> list) {
        return listToTree(JSONArray.parseArray(JSON.toJSONString(list)), "id", "parentId", "children");
    }

    /**
     * listToTree
     * <p>方法说明<p>
     * 将JSONArray数组转为树状结构
     *
     * @param arr   需要转化的数据
     * @param id    数据唯一的标识键值
     * @param parentID 父id唯一标识键值
     * @param child 子节点键值
     * @return JSONArray
     */
    public static JSONArray listToTree(JSONArray arr, String id, String parentID, String child) {
        JSONArray ar = new JSONArray();
        JSONObject hash = new JSONObject();
        //将数组转为Object的形式,key为数组中的id
        for (int i = 0; i < arr.size(); i++) {
            JSONObject json = (JSONObject) arr.get(i);
            hash.put(json.getString(id), json);
        }
        //遍历结果集
        for (int j = 0; j < arr.size(); j++) {
            //单条记录
            JSONObject aVal = (JSONObject) arr.get(j);
            //在hash中取出key为单条记录中pid的值
            JSONObject hashVP = (JSONObject) hash.get(aVal.get(parentID).toString());
            //如果记录的parentID存在,则说明它有父节点,将她添加到孩子节点的集合中
            if (hashVP != null) {
                //检查是否有child属性
                if (hashVP.get(child) != null) {
                    JSONArray ch = (JSONArray) hashVP.get(child);
                    ch.add(aVal);
                    hashVP.put(child, ch);
                } else {
                    JSONArray ch = new JSONArray();
                    ch.add(aVal);
                    hashVP.put(child, ch);
                }
            } else {
                ar.add(aVal);
            }
        }
        return ar;
    }
}

此工具了,通过传输入的集合,可以找到对应的父类以及子类集合

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以,以下是一个简单的 Java 通用树结构转换工具类: ```java import java.util.ArrayList; import java.util.List; public class TreeUtils { /** * 将通用树结构转换为指定类型树结构 * * @param sourceList 原始树结构列表 * @param rootId 根节点 ID * @param builder 转换器 * @param <T> 目标树结构节点类型 * @return 目标树结构列表 */ public static <T extends TreeNode> List<T> convertTree(List<? extends TreeNode> sourceList, String rootId, TreeBuilder<T> builder) { List<T> targetList = new ArrayList<>(); for (TreeNode sourceNode : sourceList) { if (rootId.equals(sourceNode.getParentId())) { T targetNode = builder.build(sourceNode); targetNode.setChildren(getChildren(sourceNode.getId(), sourceList, builder)); targetList.add(targetNode); } } return targetList; } /** * 获取指定节点的子节点列表 * * @param parentId 父节点 ID * @param sourceList 原始树结构列表 * @param builder 转换器 * @param <T> 目标树结构节点类型 * @return 子节点列表 */ private static <T extends TreeNode> List<T> getChildren(String parentId, List<? extends TreeNode> sourceList, TreeBuilder<T> builder) { List<T> children = new ArrayList<>(); for (TreeNode sourceNode : sourceList) { if (parentId.equals(sourceNode.getParentId())) { T targetNode = builder.build(sourceNode); targetNode.setChildren(getChildren(sourceNode.getId(), sourceList, builder)); children.add(targetNode); } } return children; } /** * 树结构节点接口 */ public interface TreeNode { /** * 获取节点 ID * * @return 节点 ID */ String getId(); /** * 获取父节点 ID * * @return 父节点 ID */ String getParentId(); } /** * 树结构节点构建器接口 * * @param <T> 目标树结构节点类型 */ public interface TreeBuilder<T extends TreeNode> { /** * 构建目标树结构节点 * * @param sourceNode 原始树结构节点 * @return 目标树结构节点 */ T build(TreeNode sourceNode); } } ``` 使用方法示例: 假设有一个 `Node` 类,表示通用树结构节点,包含 `id`、`parentId`、`name` 等属性。现在需要将 `Node` 类型通用树结构转换为 `Menu` 类型树结构,其中 `Menu` 类型的节点包含 `id`、`parentId`、`name`、`url` 等属性。可以按以下步骤进行转换: 1. 定义 `Menu` 类型的节点: ```java public class Menu implements TreeUtils.TreeNode { private String id; private String parentId; private String name; private String url; private List<Menu> children; // 省略 getter 和 setter 方法 } ``` 2. 定义 `Menu` 类型的节点构建器: ```java public class MenuBuilder implements TreeUtils.TreeBuilder<Menu> { @Override public Menu build(TreeUtils.TreeNode sourceNode) { Node node = (Node) sourceNode; Menu menu = new Menu(); menu.setId(node.getId()); menu.setParentId(node.getParentId()); menu.setName(node.getName()); menu.setUrl(node.getUrl()); return menu; } } ``` 3. 调用 `TreeUtils.convertTree()` 方法进行转换: ```java List<Node> nodeList = ... // 原始树结构列表 List<Menu> menuList = TreeUtils.convertTree(nodeList, "root", new MenuBuilder()); ``` 其中,`nodeList` 是原始树结构列表,`"root"` 是根节点 ID,`new MenuBuilder()` 是 `Menu` 类型的节点构建器。 希望这个工具类能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值