当前位置: 首页 > 工具软件 > Streams > 使用案例 >

Java8--Streams

欧阳衡
2023-12-01

Java 中的流允许定义一个操作管道,可以将输入数据转换为所需的形式。Streams 允许在任何数据源上执行操作,这些数据源可以根据 Streams API 的要求提供对其元素的访问。最常见的是,它是 Java 中的任何集合(? extends Collection)。Java 8 中增强了 Collection 以支持流。除此之外,还可以使用任何工厂方法或生成器方法来构建与流兼容的数据源。

Streams 提供了以声明方式而不是强制方式处理数据的能力。Streams 还允许将 filter-map-reduce 模式(在大多数支持函数式编程的语言中可用)应用于集合。流允许轻松无缝地顺序和并行执行操作。

Stream 不是数据结构或集合,它是对数据源执行的操作的声明性表达式。

在函数式编程术语中,流本质上是 Monads,这意味着它是一种表示定义为步骤序列的计算的结构。表示 monad 结构的类型(Java 意义上的类)定义了操作的链接和排序、基于操作及其序列的特征派生,以及将该类型与其他类似类型链接的机制。

Stream 执行流可以与 Iterator 进行比较(以代码类比)——值流过,当它们被消耗时(一旦通过终端操作执行流),它们就不再可用。

Stream 管道由三个级别组成:

1、源:

表示将数据项提供给进程的数据源。

常见的来源有:

1、Collection.stream() — 从集合的元素创建流
2、Stream.of(T…) — 从传递给工厂方法的参数创建一个流
3、Stream.of(T[]) — 从数组元素创建流
4、Stream.empty() — 创建一个空流
5、IntStream.range(lower, upper) — 创建一个由从低到高的元素组成的 IntStream,不包括lower、upper在内
6、IntStream.rangeClosed(lower, upper) — 创建一个由从下到上的元素组成的 IntStream,包括lower、upper在内。

2、零个或多个中间操作:

中间操作返回一个流,因此我们可以链接多个中间操作。中间操作的一个重要特征是惰性。中间操作只会在存在终端操作时执行

常见的中间操作有:

1、filter(Predicate) — 匹配谓词的流元素
2、map(Function) — 将提供的函数应用于流的元素的结果
3、flatMap(Function<t, stream>) — 将提供的流承载函数应用于流的元素所产生的流的元素
4、distinct() — 流的元素,删除重复项
5、sorted() — 流的元素,按自然顺序排序
6、Sorted(Comparator) — 流的元素,按提供的比较器排序
7、limit(long) — 流的元素,截断为提供的长度
8、skip(long) — 流的元素,丢弃前 N 个元素

3、单终端操作:

终端操作要么无效,要么返回非流结果。它们将让流管道执行并返回所有应用操作的执行结果。

常见的终端操作有:

1、forEach(Consumeraction) — 将提供的动作应用于流的每个元素
2、toArray() — 从流的元素创建一个数组
3、reduce(…) — 将流的元素聚合为一个汇总值
4、collect(…) — 将流的元素聚合到汇总结果容器中
5、min(Comparator) — 根据比较器返回流的最小元素
6、max(Comparator) — 根据比较器返回流的最大元素
7、count() — 返回流的大小
8、{any,all,none} Match(Predicate) — 返回流的 任何/所有/无 元素是否与提供的谓词匹配。这是短路操作
9、findFirst() — 返回流的第一个元素(如果存在)。这是短路操作
10、findAny() — 返回流的任何元素(如果存在)。

例子

1、流管道三个级别的例子:

Stream.of("1", "2", "3", "4", "5") // source
.filter(s -> s.startsWith("1")) // intermediate operation
.map(String::toUpperCase) // intermediate operation
.sorted() // intermediate operation
.forEach(System.out::println); // terminal operation

2、parallel Stream 执行的一些示例:

Arrays.asList("1", "2", "3", "4", "5")
.parallelStream() // parallel processing
.filter(s -> s.startsWith("1"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Stream.of("1", "2", "3", "4", "5")
.parallel() // parallel processing
.filter(s -> s.startsWith("1"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);

3、其他一些 Stream API 用法示例:

Stream.of("1", "2", "3", "4", "5")
.mapToInt(Integer::valueOf)
.sum();
// Output: 15

Stream.of("1", "2", "3", "4", "5")
.mapToInt(Integer::valueOf)
.reduce(0, (x,y) -> x+y);
// Output: 15

Stream.of("Java", "和", "算", "法", "学", "习")
.collect(Collectors.joining());
// Output: Java和算法学习

Stream.of("Java", "和", "算", "法", "学", "习")
.reduce("", (a,b)->a+b);
// Output: Java和算法学习

更多关于 Streams 及其在 Java 中的实现细节将在后面的文章中讲到。

 类似资料: