当前位置: 首页 > article >正文

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

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

问题背景

在以下代码中:

@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()

@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()

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

使用 toList() (静态导入)

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() 简洁而依赖上下文。

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



http://www.kler.cn/a/457289.html

相关文章:

  • 简易内存池(下)
  • Tabby设计架构介绍
  • SonarQube相关的maven配置及使用
  • mysql8 从C++源码角度看 客户端发送的sql信息 mysql服务端从网络读取到buff缓存中
  • 一份完整的营销策划包含哪些内容?营销策划主要内容和流程--中小企实战运营和营销工作室博客
  • Jenkins使用记录
  • python 不应该将列表作为函数的默认参数
  • 工业大数据分析算法实战-day14
  • 【每日学点鸿蒙知识】节点析构问题、区分手机和pad、 Navigation路由问题、Tabs组件宽度、如何监听Map
  • Sql Sqserver 相关知识总结
  • 【每日学点鸿蒙知识】Web组件加载空白、C++回调ArkTS、底部横幅隐藏显示、构建warn过多、ArkTS与C++实时通信
  • 深入了解SpringIoc(续篇)
  • Docmatix:突破性的文档视觉问答数据集
  • 从头开始学SpringMVC—01MVC介绍和入门案例
  • ​Python数据序列化模块pickle使用
  • 如何快速又安全的实现端口转发【Windows MAC linux通用】
  • yolov8算法及其改进
  • Golang的文件加密工具
  • Word批量更改题注
  • Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击
  • 问题-01
  • 学习C++:数据类型
  • Jmeter录制https请求
  • 在asp.net webapi项目中 将数据库连接字符串写在配置文件中,及Program配置Serilog存放路径以及设置
  • JavaWeb期末复习
  • Wordly Wise 3000 国际背单词01 介绍 + 测词汇量