Java 中的流允许定义一个操作管道,可以将输入数据转换为所需的形式。Streams 允许在任何数据源上执行操作,这些数据源可以根据 Streams API 的要求提供对其元素的访问。最常见的是,它是 Java 中的任何集合(? extends Collection)。Java 8 中增强了 Collection 以支持流。除此之外,还可以使用任何工厂方法或生成器方法来构建与流兼容的数据源。
Streams 提供了以声明方式而不是强制方式处理数据的能力。Streams 还允许将 filter-map-reduce 模式(在大多数支持函数式编程的语言中可用)应用于集合。流允许轻松无缝地顺序和并行执行操作。
Stream 不是数据结构或集合,它是对数据源执行的操作的声明性表达式。
在函数式编程术语中,流本质上是 Monads,这意味着它是一种表示定义为步骤序列的计算的结构。表示 monad 结构的类型(Java 意义上的类)定义了操作的链接和排序、基于操作及其序列的特征派生,以及将该类型与其他类似类型链接的机制。
Stream 执行流可以与 Iterator 进行比较(以代码类比)——值流过,当它们被消耗时(一旦通过终端操作执行流),它们就不再可用。
表示将数据项提供给进程的数据源。
常见的来源有:
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在内。
中间操作返回一个流,因此我们可以链接多个中间操作。中间操作的一个重要特征是惰性。中间操作只会在存在终端操作时执行。
常见的中间操作有:
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 个元素
终端操作要么无效,要么返回非流结果。它们将让流管道执行并返回所有应用操作的执行结果。
常见的终端操作有:
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() — 返回流的任何元素(如果存在)。
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
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);
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 中的实现细节将在后面的文章中讲到。