Java 泛型 + 函数式接口实战:简单的通用构造树方法

本文介绍了如何在Java项目中通过使用泛型和函数式接口来避免因多个分类树节点属性不同但构造逻辑相同导致的代码冗余,创建了一个通用的TreeUtils类,用于递归构建树结构并进行设置子节点的操作。
摘要由CSDN通过智能技术生成

目录

问题

如何解决

代码


问题

一个Java项目中,有多个分类树,每个分类树上节点的属性各不相同,但是构造分类树的逻辑又都是一样的。每个分类树构造都要单独写一个方法的话,会造成代码冗余。

如何解决

使用Java泛型+函数式接口,提取公用逻辑。

代码

构造树工具类

public class TreeUtils {

    public final static String ROOT = "root";

    /**
     * 递归构造树
     *
     * @param sources 按parentId分类的节点
     * @param parentId 父id
     * @param getId 获取id
     * @param setChildren 设置子节点
     * @return 根节点集合
     * @param <T> 节点类
     * @param <R> id类型
     */
    public static <T, R> List<T> buildTree(Map<R, List<T>> sources, R parentId,
                                        Function<T, R> getId, BiConsumer<T, List<T>> setChildren) {
        List<T> nodes = sources.getOrDefault(parentId, emptyList());

        for (T node : nodes) {
            List<T> subNodes = buildTree(sources, getId.apply(node), getId, setChildren);
            setChildren.accept(node, subNodes);
        }

        return nodes;
    }

    //测试代码
    public static void main(String[] args) {
        Node root = new Node();
        root.setId("1");
        root.setPid(null);
        root.setName("root");

        Node child1 = new Node();
        child1.setId("2");
        child1.setPid("1");
        child1.setName("child1");

        Node child2 = new Node();
        child2.setId("3");
        child2.setPid("1");
        child2.setName("child2");

        List<Node> children = Arrays.asList(child1, child2);
        root.setChildren(children);

        List<Node> nodes = Arrays.asList(root, child1, child2);
        Map<String, List<Node>> sources = nodes.stream()
                .collect(groupingBy(e -> Objects.isNull(e.getPid()) ? ROOT : e.getPid()));

        TreeUtils.buildTree(sources, ROOT, Node::getId, Node::setChildren);
    }

}

//节点实体类
class Node {
    private String id;
    private String pid;
    private String name;
    private List<Node> children;

    public String getId() {
        return id;
    }

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

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public void setChildren(List<Node> children) {
        this.children = children;
    }
}
  • 41
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值