Stream

概述

Java SE 8引入的java.util.stream包,用于为可能并行处理批量操作建立声明式的表达式.它充分利用了lambda表达式.

流的使用

例如对满足过滤条件的单词进行计数

List<String> words = Arrays.asList("a", "bc");
long count =  words.stream().filter(w->w.length()>1).count();

如果将stream()修改为parallelStream(),就可以让流库以并行方式进行过滤和计数,多核处理下提高性能.

使用流的关键思想使客户端代码告诉流库该做什么,怎么做由流库实现.

流的生命周期

每个流都有一个创建来源,若干个中间操作,以及一个终止操作.

流的创建

常见流创建方法:

方法描述
Collection.stream()使用一个集合的元素创建一个流。
Stream.of(T... values)使用传递给工厂方法的参数创建一个流。
Stream.empty()创建一个空流。
Stream.generate(Supplier<T> s)使用一个生成器函数创建一个无限流。
Stream.iterate(T first, BinaryOperator<T> f)创建一个包含序列 first, f(first), f(f(first)), ... 的无限流
IntStream.range(lower, upper)创建一个由下限到上限(不含)之间的元素组成的 IntStream。
IntStream.rangeClosed(lower, upper)创建一个由下限到上限(含)之间的元素组成的 IntStream。
Arrays.stream(T... values)同Stream.of(T... values)

中间操作

操作内容
filter(Predicate<T>)产生一个流,包含匹配的元素
map(Function<? super T, ? extends R> mapper)产生一个流,每个元素由mapper转换上一个流元素产生
flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);产生一个流,将流元素进行平铺展开并连接到一起,连接后的新流应用mapper([["a","b","c"],["d"]]=>["a","b","c","d"])
distinct()删除重复元素
sorted()按自然顺序排序的流元素
sorted(Comparator<? super T> comparator)按给定比较器排序的流元素
limit(long maxSize)阶段到指定长度
skip(long n);丢弃前n个元素
peek(Consumer<? super T> action);产生一个流,获取的元素会传递给action
中间操作始终使惰性的,可进一步划分为无状态和有状态。无状态例如(map,filter),有状态例如(sorted,distinct)

终止操作

终止操作会结束流管道,并产生结果

操作描述
forEach(Consumer<T>)将提供的操作应用于流的每个元素。
toArray使用流元素创建一个数组。
reduce(T identity, BinaryOperator<T>)将流的元素聚合为一个汇总值
collect(...)将流的元素聚合到一个汇总结果容器中。
min(Comparator<? super T>)最小值
max(Comparator<? super T>)最大值
count流大小
{any,all,none}Match(Predicate<T>)返回流的任何/所有元素是否与提供的预期相匹配。
Optional<T> findFirst返回流的第一个元素
Optional<T> findAny返回流的任何元素

Optional

Optional<T> 是一个包装器

get方法,如果包装对象为空会抛出异常,

可以使用orElse提供默认值

Stream s = Stream.iterate(1, t -> t + 1).limit(10);
Optional first = s.findFirst();
first.orElse(2);
Last Updated:
Contributors: himcs, himcs