Java树结构递归构建优化

引子:从一个问题开始

在日常开发中,树形结构的构建是一个常见的需求,例如分类、菜单、组织架构等场景。而随着Java版本的不断更新,一些新的特性如Java 11中的String.repeat方法和Map.getOrDefault方法为我们提供了更简洁、优雅的解决方案。同时,借助 Lombok 注解,我们可以进一步减少冗余代码,提升开发效率。

假设我们有一个类型表,包含以下字段:

  • id: 节点唯一标识
  • code: 分类代码
  • name: 分类名称
  • parentId: 父节点ID(根节点为0)

我们需要根据这个表构建一个树形结构,并以缩进的形式打印出来。例如:

一级分类
    二级分类
        三级分类
一级分类(1)
    二级分类

面对这样的需求,本文将结合 Lombok 和 Java 11的新特性,展示如何优雅地实现树结构的递归构建。

核心实现:树结构递归构建

1. 定义实体类(使用 Lombok 优化)

通过 Lombok@Data 注解,我们可以自动生成 gettersettertoString 方法,从而避免手动编写这些基础代码。

import lombok.Data;

import java.util.List;

@Data // 自动生成 getter、setter 和 toString 方法
public class TreeNode {
    private int id;
    private String code;
    private String name;
    private int parentId;
    private List<TreeNode> children = new ArrayList<>();
}

2. 数据准备与测试用例

模拟一个包含分类信息的列表,每个分类用 TreeNode 对象表示。

import org.junit.jupiter.api.Test;

import java.util.*;

public class TreeBuilderTest {

    @Test
    public void typeTree() {
        List<TreeNode> list = new ArrayList<>();
        list.add(new TreeNode(1, "1", "一级分类", 0));
        list.add(new TreeNode(2, "2", "一级分类(1)", 0));
        list.add(new TreeNode(3, "3", "二级分类", 1));
        list.add(new TreeNode(4, "4", "三级分类", 3));
        list.add(new TreeNode(5, "5", "二级分类", 2));

        // 构建树结构
        List<TreeNode> treeList = buildTree(list);
        printTree(treeList, 0);
    }

    public List<TreeNode> buildTree(List<TreeNode> list) {
        Map<Integer, List<TreeNode>> listMap = list.stream()
                .collect(Collectors.groupingBy(TreeNode::getParentId));
        List<TreeNode> rootList = listMap.getOrDefault(0, Collections.emptyList());
        setChildren(rootList, listMap);
        return rootList;
    }

    public void setChildren(List<TreeNode> rootList, Map<Integer, List<TreeNode>> listMap) {
        rootList.forEach(root -> {
            List<TreeNode> children = listMap.getOrDefault(root.getId(), Collections.emptyList());
            if (!children.isEmpty()) {
                root.setChildren(children);
                setChildren(children, listMap);
            }
        });
    }

    public void printTree(List<TreeNode> nodes, int level) {
        for (TreeNode node : nodes) {
            System.out.println(" ".repeat(level * 4) + node.getName());
            printTree(node.getChildren(), level + 1);
        }
    }
}

3. 运行结果

假设输入的数据如上所示,运行程序后输出的树结构如下:

一级分类
    二级分类
        三级分类
一级分类(1)
    二級分类

Java 11中的String.repeat方法详解

String.repeat(int count) 是 Java 11 引入的一个新方法,用于将字符串重复指定次数。它的语法简单直观,可以显著简化代码。

示例

public class RepeatExample {
    public static void main(String[] args) {
        String str = "Hello";
        int times = 3;

        // 使用 repeat 方法
        String result = str.repeat(times);

        System.out.println(result); // 输出: HelloHelloHello
    }
}

特点

  • 避免冗余代码:无需手动拼接字符串。
  • 提高可读性:代码更加简洁明了。
  • 性能优化:底层实现了高效的重复操作。

Map.getOrDefault方法详解

Map.getOrDefault(Object key, V defaultValue) 是 Map 接口提供的一个方法,用于获取指定键的值。如果键不存在,则返回默认值。

示例

Map<Integer, String> map = new HashMap<>();
map.put(1, "Value1");

// 使用 getOrDefault 方法
String value = map.getOrDefault(2, "DefaultValue");
System.out.println(value); // 输出: DefaultValue

特点

  • 避免空指针异常:直接返回默认值,无需额外判断。
  • 简化代码:减少了显式的 if-else 逻辑。
  • 适用场景:适用于简单的键值查找场景。

总结

本文通过一个树结构递归构建的案例,详细介绍了如何结合 Lombok 和 Java 11 的新特性来优化代码:

  • Lombok 的 @Data 注解:自动生成 gettersetter 和 toString 方法,减少冗余代码。
  • Java 11 的 String.repeat 方法:用于生成重复字符串,尤其在格式化输出时非常有用。
  • Map.getOrDefault 方法:适合处理可能为空的键值查找场景,简化了代码逻辑。

希望本文能为你提供一些启发,在实际开发中灵活运用这些特性,提升代码质量!如果你还有其他问题或需要进一步探讨,请随时留言交流。

感谢阅读!欢迎点赞、收藏和评论,一起学习进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值