在Java 8及更高版本中使用Java流

JAVA8已经发布了八年多 , 但2014年发布的许多特性都延续到了2022年 。其中最突出的是Java流 。在这篇文章中 , 我们解释了什么是Java流 , 解释了何时使用它们 。并简要介绍了常见的Java流操作 。
Java中的流是什么?
Java流支持对元素流的函数式操作 。流是以某种顺序应用于数据的不可变函数集合的抽象 。流不是可以存储元素的集合 。
流和结构之间最重要的区别是流不保存数据 。例如 , 你不能指向流中某个元素存在的位置 。你只能指定对该数据进行操作的函数 。并且在流上执行操作时 , 会影响原流 。
注意 , 这个文章中的流不要与Java I/O包中的流混淆 , 如InputStream、OutputStream等 。
何时使用Java流
Java流代表了数据流动的管道和对数据进行操作的函数 。在这种情况下 , 管道由一个流源、零个或多个中间操作以及一个终端操作组成 。因此 , 流可以用在任何涉及数据驱动函数的应用程序中 。
在下面的例子中 , Java流被用作一个奇特的迭代器:

在Java 8及更高版本中使用Java流

文章插图
在这个例子中 , 我们只选择偶数值 , 通过使用过滤器方法 , 并将它们增加了一倍绘图使输入加倍的函数 。这给我们提供了什么?streams API为我们提供了在各个步骤中指定数据操作序列的能力 。我们不指定任何条件处理代码 , 我们不想编写大型复杂函数 , 我们不关心数据流 。
事实上 , 我们一次只为一个数据处理步骤而烦恼:我们通过streams框架的能力自己组合函数和通过函数的数据流 。上面的例子显示了你最终将在流中使用的最重要的模式之一:
将集合提升到流 。
骑流:过滤值 , 转换值 , 限制输出 。
组成小的个体操作 。
将结果收集回具体的集合中 。
流中的常见操作
在Java 8及更高版本中 , 你可以通过调用stream()方法轻松地从任何集合中获取流 。之后 , 还有几个你会经常遇到的基本函数 。
在Java 8及更高版本中使用Java流

文章插图
以下是Java流中的一些常见操作:
过滤器:返回一个新流 , 其中包含原始流的一些元素 。它接受谓词来计算应该在新流中返回哪些元素 , 并删除其余的元素 。在命令式代码中 , 我们会使用条件逻辑来指定应该发生什么如果一个元素满足条件 。在功能性的风格中 , 我们不用费心可安装文件系统 , 我们过滤流 , 只处理我们需要的值 。
地图:将流元素转换成其他东西 , 它接受一个应用于流中每个元素的函数 , 并返回参数函数产生的值的流 。这是Java流API的基础 。Map允许你对流中的数据执行计算 。
减少:(有时也称为折叠)将流简化为单个元素 。如果你想要对流中的所有整数值求和 , 你需要使用reduce函数 。如果你想在流中找到最大值 , reduce就是你的朋友 。
收集:这是走出流世界并获得具体的值集合的方法 , 就像上面例子中的列表一样 。
你不会在每次遇到流时都使用所有这些函数 , 但是你可以随意使用它们 。
关于Java Streams API的最终想法
并行运行每个流操作存在缺陷 , 大多数streams实现使用默认的ForkJoinPool在后台执行操作 。因此 , 你可以很容易地使特定的流处理稍微快一点 , 但是却牺牲了整个JVM的性能 , 甚至没有意识到这一点 。
使用函数式编程解决问题需要不同的思维方式 。但是通过一点试验 , 你就能掌握它的窍门 。
【在Java 8及更高版本中使用Java流】通常 , 你可能很难找到一个实用的解决方案 , 但是一旦你得到了 , 你就会意识到它并不特别复杂 。然后下一次解决类似的问题就容易多了 。




    推荐阅读