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);