news 2026/4/29 4:40:41

300. Java Stream API - 收集 Stream 元素到集合或数组(Java Stream 收集器详解)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
300. Java Stream API - 收集 Stream 元素到集合或数组(Java Stream 收集器详解)

300. Java Stream API - 收集 Stream 元素到集合或数组(Java Stream 收集器详解)

Java 的 Stream API 提供了多种方式来将流中的元素收集到集合中,比如 List、Set、数组等。你在上一节已经见识过其中的一两个例子,本节我们来深入挖掘各种实用模式及其适用场景。


🧭 在选择收集方式前,你应先思考几个关键问题:

  • 🔒 是否需要一个不可变(unmodifiable)的集合?
  • 🧺 是否需要一个具体的集合类型(如ArrayListLinkedList或自定义实现)?
  • 📏 是否能预估元素数量?(这将影响性能优化)
  • 🧩 是否需要与第三方库的集合实现兼容?

这些因素会影响你最终的收集方式选择。接下来我们逐一介绍各种场景下的典型收集方式。


🚀 1. 收集到可变ArrayList(默认方式)

这是最常用也最简单的方式:

Stream<String>strings=Stream.of("one","two","three","four");List<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).collect(Collectors.toList());System.out.println("result = "+result);

🧾 输出:

result=[ONE,TWO]

📌 特点:

  • 返回一个普通的ArrayList
  • 简洁 ✅,可变 ✅,性能中等 ⚠️(当元素数量大时,可能触发内部数组扩容)

🎯 2. 自定义集合类型或预设容量(toCollection

当你:

  • 想使用其他集合类型(如LinkedList
  • 或者你知道将要收集多少元素(可优化容量)

可使用Collectors.toCollection(...)

Stream<Integer>ints=IntStream.range(0,10_000).boxed();List<String>result=ints.map(String::valueOf).collect(Collectors.toCollection(()->newArrayList<>(10_000)));System.out.println("# result size = "+result.size());

🧠 好处:

  • 避免ArrayList多次扩容
  • 可替换为LinkedList::newCopyOnWriteArrayList::new等工厂方法

🔒 3. 收集为不可变 List(Java 10+)

✅ 使用Collectors.toUnmodifiableList()

Stream<String>strings=Stream.of("one","two","three","four");List<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).collect(Collectors.toUnmodifiableList());System.out.println("result = "+result);

📌 输出:

result=[ONE,TWO]

⚠️ 尝试修改result.add(...)会抛出UnsupportedOperationException


🚀 4. 更高效的不可变 List(Java 16+)

✅ 使用新方法.toList()

Stream<String>strings=Stream.of("one","two","three","four");List<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).toList();System.out.println("result = "+result);

📌 输出:

result=[ONE,TWO]

⚙️ 为什么更高效?

  • .collect(Collectors.toUnmodifiableList())的底层实现是:
    1. 收集到一个ArrayList
    2. 再封装为不可变集合(多了一步)
  • .toList()则更聪明:如果能预估流的长度,它会一次性分配数组空间,避免扩容与拷贝JDK 16优化)

🔢 5. 收集到数组(使用toArray

❌ 简单版(类型擦除):

Object[]result=Stream.of("a","b","c").toArray();
  • 不推荐!返回Object[],类型丢失。

✅ 推荐写法(保留数组类型):

String[]result=Stream.of("one","two","three","four").filter(s->s.length()==3).map(String::toUpperCase).toArray(String[]::new);System.out.println(Arrays.toString(result));

📌 输出:

[ONE,TWO]

🧠 背后的语法糖:

String[]::new==size->newString[size]

📝 各种收集方式总结对比表

模式返回类型可变性Java 版本适用场景说明
collect(Collectors.toList())ArrayList✅ 可变Java 8+默认收集方式,简单好用
collect(toCollection(...))任意集合类型✅ 可变Java 8+自定义集合或设置初始容量
collect(toUnmodifiableList())ImmutableList❌ 不可变Java 10+需要只读集合,防止误修改
stream.toList()ImmutableList❌ 不可变Java 16+更高效的不可变收集,推荐
toArray(String[]::new)数组✅ 可变Java 8+需要收集成固定类型数组
toArray()Object[]✅ 可变Java 8+不推荐,类型擦除
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 15:32:44

零基础玩转YOLO26:官方镜像保姆级教程

零基础玩转YOLO26&#xff1a;官方镜像保姆级教程 你是不是也曾经被目标检测的复杂环境配置劝退&#xff1f;下载依赖、编译框架、调试版本冲突……光是准备阶段就能耗掉一整天。现在&#xff0c;这一切都成了过去式。 今天要介绍的 “最新 YOLO26 官方版训练与推理镜像”&am…

作者头像 李华
网站建设 2026/4/17 23:15:04

如何判断是否需要GPEN修复?这3种情况最适用

如何判断是否需要GPEN修复&#xff1f;这3种情况最适用 1. 老照片模糊褪色&#xff0c;细节严重丢失 1.1 常见问题表现 你有没有翻出过家里的老相册&#xff0c;想看看父母年轻时的模样&#xff0c;却发现照片早已泛黄、模糊不清&#xff1f;或者某张珍贵的合影因为年代久远…

作者头像 李华
网站建设 2026/4/19 1:53:11

小白也能用!SenseVoiceSmall语音理解镜像保姆级入门教程

小白也能用&#xff01;SenseVoiceSmall语音理解镜像保姆级入门教程 你是不是也遇到过这样的问题&#xff1a;一段音频里既有说话内容&#xff0c;又有背景音乐、笑声或情绪波动&#xff0c;但普通语音转文字工具只能输出干巴巴的文字&#xff1f;现在&#xff0c;阿里开源的 …

作者头像 李华