Stream `Collectors.toList()` 和 `Stream.toList()` 的区别(Java)

Stream Collectors.toList()Stream.toList() 的区别

问题背景

在以下代码中:

java 复制代码
@Test
void test() {
    JSONArray nodes = new JSONArray();
    String[] names = {"df1", "df2", "df3"};
    for (String name : names) {
        JSONObject obj = new JSONObject();
        obj.put(Constants.NAME, name);
        nodes.add(obj);
    }

    // 流式操作
    List<String> dfname = nodes.stream()
            .map(JSONObject.class::cast)
            .map(json -> json.getString("name"))
            .collect(Collectors.toList());

    // 输出验证
    System.out.println(dfname); // [df1, df2, df3]

    boolean df1 = dfname.contains("df1");
    boolean df2 = dfname.contains("df2222");
    System.out.println(df1);
    System.out.println(df2);
}

问题:是否可以将 .collect(Collectors.toList()) 替换为 .toList()

以下对两者进行详细分析。

区别

1. Collectors.toList()
  • 来源 :来自 java.util.stream.Collectors
  • 特性
    • 返回的是一个 可变的列表 ,通常是 ArrayList
    • 允许修改列表内容,例如 add()remove() 等操作。
    • 支持从 Java 8 开始。
2. Stream.toList()
  • 来源 :从 Java 16 引入的新方法,属于 java.util.stream.Stream 类。
  • 特性
    • 返回的是一个 不可变的列表 ,类似 List.of()
    • 修改列表内容会抛出 UnsupportedOperationException
    • 代码更简洁,不需要额外导入 Collectors

区别详情

特性 Collectors.toList() Stream.toList()
返回的 List 类型 可变(例如 ArrayList 不可变(ImmutableCollections.ListN
Java 版本 从 Java 8 开始支持 从 Java 16 开始支持
修改性操作支持 支持,返回的 List 可以修改,如 add()remove() 等。 不支持,尝试修改会抛出 UnsupportedOperationException
依赖 Collectors 是的,需要导入 java.util.stream.Collectors 否,不需要额外导入。

替换方式示例

在代码中,由于没有对返回的 List 进行修改,可以使用 toList()

java 复制代码
@Test
void test() {
    JSONArray nodes = new JSONArray();
    String[] names = {"df1", "df2", "df3"};
    for (String name : names) {
        JSONObject obj = new JSONObject();
        obj.put(Constants.NAME, name);
        nodes.add(obj);
    }

    // 使用 toList()
    List<String> dfname = nodes.stream()
            .map(JSONObject.class::cast)
            .map(json -> json.getString("name"))
            .toList(); // 替换为 toList()

    // 输出验证
    System.out.println(dfname); // [df1, df2, df3]

    boolean df1 = dfname.contains("df1");
    boolean df2 = dfname.contains("df2222");
    System.out.println(df1);
    System.out.println(df2);
}

选择依据

  • 如果需要返回一个可变列表 (可以 add() 或修改),应使用 Collectors.toList()
  • 如果不需要修改返回的列表 ,且代码运行在 Java 16 及以上,推荐使用 toList(),代码更简洁且线程安全。

总结

两者在功能上没有差别(在逻辑正确的前提下),选择使用哪个取决于:

  • Java 版本 :低于 Java 16 只能用 Collectors.toList()
  • 可变性需求 :如果需要修改返回的 List,选择 Collectors.toList()

.collect(Collectors.toList());.collect(toList()); 本质上是等效的。两者都用于将流中的元素收集到一个 List 中。但是,它们之间的主要区别在于 方法引用的静态导入代码风格

区别分析

1. .collect(Collectors.toList());

  • 是一种完整的写法,显式地使用 Collectors.toList() 方法。
  • 不需要静态导入,代码的意图更明确。
  • 缺点是显得稍微冗长。

2. .collect(toList());

  • 需要静态导入 java.util.stream.Collectors.toList 方法。
  • 静态导入后可以省略 Collectors.,代码更简洁。
  • 依赖静态导入,可能会让代码在阅读时需要结合上下文才能清楚实际方法。

示例代码

使用 Collectors.toList()

java 复制代码
@Test
void testWithCollectors() {
    List<String> list = Stream.of("A", "B", "C")
            .collect(Collectors.toList()); // 完整写法
}

使用 toList() (静态导入)

java 复制代码
import static java.util.stream.Collectors.toList;

@Test
void testWithStaticImport() {
    List<String> list = Stream.of("A", "B", "C")
            .collect(toList()); // 静态导入方式
}

使用建议

  1. 明确性优先

    • 当团队中存在新手或对静态导入感到不熟悉时,推荐使用 Collectors.toList() 这种完整的形式。
  2. 简洁性优先

    • 对于内部代码或约定明确的项目,可以使用静态导入 toList() 的形式。

总结

两者的功能和效果没有任何差异,主要区别在于代码的书写方式。

  • 完整写法Collectors.toList() 明确而冗长。
  • 静态导入写法toList() 简洁而依赖上下文。

选择具体写法时可以根据代码的风格要求、团队的熟悉程度进行选择。


相关推荐
九转苍翎26 分钟前
Java SE(10)——抽象类&接口
java
明月与玄武27 分钟前
Spring Boot中的拦截器!
java·spring boot·后端
矢鱼27 分钟前
单调栈模版型题目(3)
java·开发语言
n33(NK)34 分钟前
Java中的内部类详解
java·开发语言
为美好的生活献上中指36 分钟前
java每日精进 5.07【框架之数据权限】
java·开发语言·mysql·spring·spring cloud·数据权限
菲兹园长1 小时前
SpringBoot统一功能处理
java·spring boot·后端
一刀到底2111 小时前
java 多核,多线程,分布式 并发编程的现状 :从本身的jdk ,到 spring ,到其它第三方。
java·分布式·高并发
Kendra9191 小时前
Docker 容器 - Dockerfile
java·docker·eureka
Auc242 小时前
Java 原生实现代码沙箱(OJ判题系统第1期)——设计思路、实现步骤、代码实现
java·开发语言·python
livemetee2 小时前
netty单线程并发量评估对比tomcat
java·tomcat·netty