流式转数组:我如何不再害怕并爱上 Java 8 中的 toArray()

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

永恒的问题:如何从流中创建数组?

\n\n

你好,同行!如果你曾经使用过 Java 8 及更高版本编写代码,你肯定遇到过这种情况:你有一个 Stream——很酷、很现代、功能强大——但突然需要一个老式的数组。可能是库的 API 要求数组,或者你想将数据传递给一个不兼容集合的方法。这时你就会陷入困境:"How can I convert a Java 8 Stream to an Array?" —— 是的,就是那个在 Stack Overflow 上积累了数千次浏览的问题。

\n\n

看起来很简单,对吧?但其中有一些细微差别。在本文中,我们将介绍所有方法:从简单的 toArray() 到使用构造器引用的高级用法。你将了解为什么 stream.toArray() 返回 Object[] 而不是 String[],以及如何解决这个问题。我们开始吧!

\n\n

目录(用于导航)

\n\n\n

为什么需要将 Stream 转换为 Array?

\n

在深入代码之前,让我们先了解一下动机。Stream API 是用于数据处理(过滤、映射、排序)的强大工具。但有些场景下,数组更方便:

\n
    \n
  • 与遗留代码的兼容性:旧方法通常只接受 String[] 或 int[]。
  • \n
  • 性能:在某些情况下,数组比列表运行得更快,尤其是当大小固定时。
  • \n
  • 处理可变参数:像 void doSomething(String... args) 这样的方法期望一个数组。
  • \n
  • JSON 序列化:许多库(例如 Jackson)与数组配合得更好。
  • \n
\n

因此,能够快速将流转换为数组是任何 Java 开发人员的基本技能。开始吧!

\n\n

方法 1:toArray() —— 最简单(但有陷阱)

\n

我们从经典方法开始。每个 Stream 都有一个 toArray() 方法,它返回 Object[]。看起来像这样:

\n\n
Stream<String> stream = Stream.of("Java", "Python", "Ruby");\nObject[] array = stream.toArray();\n\n// 输出:[Java, Python, Ruby]\nSystem.out.println(Arrays.toString(array));\n
\n\n

一切正常——但有一个陷阱。得到的数组类型是 Object[],而不是 String[]。如果你确实需要 String[],则必须进行强制转换:

\n\n
String[] stringArray = (String[]) stream.toArray(); // ClassCastException!\n
\n\n

错误! Java 无法将 Object[] 强制转换为 String[]——它们是不同的类型。因此,只有当你准备好使用 Object[] 时,无参数的 toArray() 才适用。但这很少见。该怎么办?继续往下看。

\n\n

方法 2:toArray(IntFunction) —— 泛型来帮忙

\n

Java 8 为我们带来了重载版本 toArray(IntFunction<A[]> generator)。此方法接受一个创建所需类型数组的函数。IntFunction 是一个函数式接口,它接受一个 int(数组大小)并返回一个数组。

\n\n

最直观的例子是通过 lambda 使用数组构造器:

\n\n
Stream<String> stream = Stream.of("Java", "Python", "Ruby");\nString[] array = stream.toArray(size -> new Str                

博客

书籍推荐