- 流的来源
从集合创建:Collection.stream()
工厂方法:Stream.of(T...)
数组创建:Stream.of(T[]) 或Arrays.stream()
空流:Stream.empty()
迭代器:Stream.iterate(T first, BinaryOperator<T> f)
生成器:Stream.generate(Supplier<T> f)
区间流:IntStream.range(lower, upper)
闭区间流:IntStream.rangeClosed(lower, upper)
文件行流:BufferedReader.lines()
代码片段:
// Collection.stream()
Arrays.asList(1, 2, 3, 4, 5).stream();
// Stream.of(T...)
Stream.of(1, 2, 3, 4, 5);
// Stream.of(T[])
Stream.of(new int[] { 1, 2, 3 });
// Stream.empty()
Stream.empty();
// Stream.iterate(T first, BinaryOperator<T> f)
Stream.iterate(1, x -> x + 1);
// Stream.iterate(T first, Predicate<T> test, BinaryOperator<T> f) //java9
// Stream.generate(Supplier<T> f)
Stream.generate(new Random()::nextInt);
// IntStream.range(lower, upper)
IntStream.range(1, 6);
// IntStream.rangeClosed(lower, upper)
IntStream.rangeClosed(1, 5);
// BufferedReader.lines()
new BufferedReader(new FileReader("test.txt")).lines();
- 中间操作
filter(Predicate<T>) 与预期匹配的流的元素
map(Function<T, U>) 将提供的函数应用于流的元素的结果
flatMap(Function<T, Stream<U>> 将提供的流处理函数应用于流元素后获得的流元素
distinct() 已删除了重复的流元素
sorted() 按自然顺序排序的流元素
Sorted(Comparator<T>) 按提供的比较符排序的流元素
limit(long) 截断至所提供长度的流元素
skip(long) 丢弃了前 N个元素的流元素
takeWhile(Predicate<T>) (仅限 Java 9)在第一个提供的预期不是 true的元素处阶段的流元素
dropWhile(Predicate<T>) (仅限 Java 9)丢弃了所提供的预期为 true的初始元素分段的流元素
代码片段
IntStream.rangeClosed(1, 5) // 产生1到5
// filter(Predicate<T>) 与预期匹配的流的元素
.filter(x -> x % 2 == 0) // 留下 2,4
// map(Function<T, U>) 将提供的函数应用于流的元素的结果
.map(x -> x * x) // 产生 4,16
// flatMap(Function<T, Stream<U>> 将提供的流处理函数应用于流元素后获得的流元素
.flatMap(x -> IntStream.of(x)) // 此处没啥意义
// distinct() 已删除了重复的流元素
.distinct() // 去掉重复
// sorted() 按自然顺序排序的流元素
.sorted() // 排序
// Sorted(Comparator<T>) 按提供的比较符排序的流元素
// limit(long) 截断至所提供长度的流元素
.limit(3) // 取前三个
// skip(long) 丢弃了前 N 个元素的流元素
.skip(1) // 跳过一个
.forEach(System.out::print);
// takeWhile(Predicate<T>) (仅限 Java 9)在第一个提供的预期不是 true 的元素处阶段的流元素
// dropWhile(Predicate<T>) (仅限 Java 9)丢弃了所提供的预期为 true 的初始元素分段的流元素
- 终端流
forEach(Consumer<T> action) 将提供的操作应用于流的每个元素。
toArray()使用流的元素创建一个数组。
reduce(...)将流的元素聚合为一个汇总值。
collect(...)将流的元素聚合到一个汇总结果容器中。
min(Comparator<T>) 通过比较符返回流的最小元素。
max(Comparator<T>) 通过比较符返回流的最大元素。
count() 返回流的大小。
{any,all,none}Match(Predicate<T>) 返回流的任何/所有元素是否与提供的预期相匹配。
findFirst()返回流的第一个元素(如果有)。
findAny()返回流的任何元素(如果有)。
代码片段
IntStream.rangeClosed(1, 10)
// 注意,由于以下流只能消费一次,以下代码只能执行一行
.forEach(System.out::println);
// .toArray();
// .reduce(Integer::sum);
// .collect(toList());
// .min();
// .max();
// .count();
// .findAny();
- 搜集器
折叠,类似满足结合律的东西可以任意分区操作,比如累加,每个线程有自己的累加器,最后合并
<R> collect(Supplier<R> resultSupplier, //初始化一个空容器
BiConsumer<R, T> accumulator, //每个线程的容器
BiConsumer<R, R> combiner)//汇总
代码片段:
IntStream.range(1, 100).collect(ArrayList::new,
(lists, element) -> lists.add(element),
(list1, list2) -> list1.addAll(list2));
以下是内置简化版的搜集器
toList()
toSet()
toCollection(Supplier<Collection>)
toMap(Function<T, K>, Function<T, V>)
summingInt(ToIntFunction<T>)
summarizingInt(ToIntFunction<T>)
reducing()
partitioningBy(Predicate<T>)
partitioningBy(Predicate<T>, Collector)
groupingBy(Function<T,U>)
groupingBy(Function<T,U>, Collector)
minBy(BinaryOperator<T>)
mapping(Function<T,U>, Collector)
joining()
counting()
流的几点说明:
- 由于Stream流使用泛型,因此都是包装类型,若涉及计算,可转化相关IntStream,DoubleStream,LongStream
- 中间操作是惰性的,只有终端操作才会触发真正的计算
- 并行parallel()背后是forkjoin框架
- 折叠,类似满足结合律的东西可以任意分区操作,易与并行
涉及代码GitHub: https://github.com/aloneload/JdkFeatures