《Java核心技术 卷2 高级特性》一

第一章 Java SE 8 的流库

流的定义

假设,words作为一个列表(List)类的实例,它存储了某本书的所有单词,现在需要对该书的长单词进行统计
根据一般的迭代方法

long count=0;
for(String w:words){
if(w.length()>12) count++;
}

而使用流的方法

long count = words.stream().filter(w->w.length()>12).count();

这里,stream方法会产生一个用于words列表的流(stream);filter方法会返回另一个流,其中包含长度大于12的单词;
count方法会将这个流简化为一个结果。

所以什么是流呢?书上说“流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图”。
流遵循着“做什么而非怎么做”的原则,就刚才的例子而言,相比迭代来说,用流来实现就不必指定具体该如何遍历列表等工作

流的创建

如果你有一个数组,那么可以使用静态的Stream.of方法

Stream<String> song = Stream.of("gently","down","the","stream");

而使用Array.stream(array,from,to)可以从数组中位于from(包括)和to(不包括)的元素中创建一个元素
若要创建不包含任何元素的流,可以使用Stream.empty();
Stream还有两个用于产生无限流的静态方法:generate方法和iterate方法

流的转换

流的转换会产生一个新的流,它的元素派生自另一个流中的元素
例如filter转换会产生一个流,它的元素和某种条件相匹配
能实现流转换的还有map和flatMap等,使用map时,会有一个函数应用到每个元素上,并且其结果是包含了应用该函数后所产生的所有结果的流
假设我们有一个字符串流上映射letters方法:

Stream<stream<String>> result = words.stream().map(w->letters(w));

那么得到一个包含流的流,就像[...["y","o","u","r"],["b","o","a","t"]...]。
为了将其摊平为字母流,可以使用flatMap方法

Stream<string> result = words.stream().flatMap(w->letters(w));

得到的结果为:[..."y","o","u","r","b","o","a","t",...]
stream.limit(n)会返回一个新的流,它在前n个元素之后结束
stream.skip(n),会返回一个新的流,但是会丢弃前n个元素
Stream类的静态contact方法会将两个流连接起来
distinct方法,会返回一个流,但是会剔除重复的元素
也可以使用sorted方法对流中的元素进行排序

简单约简

即如何从数据流中获取答案,约简是一种终结操作,它们会将流约简为可以在程序中使用的非流值
count方法就是一个例子,它返回流中元素的数量
其余的约简还有max和min方法,它们会返回最大值和最小值
还有经常与filter流转换方法搭配使用的findFirst、findAny、anyMatch、allMatch、noneMatch方法
这些方法返回的是一份类型Optional<T>的值,它要么包装了答案,要么表示没有任何值

至此,我们介绍了操作流的典型流程,即:
    1.创建一个流
    2.指定初始流转换为其他流的中间操作,可能包含多个步骤
    3.应用终止操作,从而产生结果

收集结果

当处理完流之后,若是想要查看流中的元素或者是想要将流中的元素收集到某些数据结构(如数组,集合和映射)中
可以调用toArray方法获得由流的元素构成的数组

String[] result = stream.toArray(String::new);

但是toArray方法返回的是Object[]数组,若是想要其具有正确的类型可以将其传递到数组构造器中

除了toArray方法外,还有一个便捷方法collect可用,如为了将流收集到列表或者集中

List<String> result = stream.collect(Collectors.toList());
//或者
Set<String> result = stream.collect(Collectors.toSet());

还可以利用Collectors.toMap方法将流收集到映射表中
toMap方法中有两个函数引元,它们用来生成映射表的键和值

除此之外,还可以利用groupingby方法来将具有相同特性的值聚集成组,groupingby方法会产生一个映射表,它的每一个值都是一个列表
如果想要以某种方式来处理这些列表,就需要提供一个“下游收集器”

基本类型流和并行流

基本类型流如:IntStream,LongStream和Doublestream
为了创建IntStream,需要调用IntStream.of和Arrays.Stream方法

IntStream stream = IntStream.of(1,1,2,3,5);
Stream = Arrays.Stream(values,from,to);

并行流
    可以使用Collection.parallelStream()方法从任何集合中获取一个并行流
    只要在终结方法执行时,流处于并行模式,那么所有的中间操作都将被并行化

猜你喜欢

转载自www.cnblogs.com/ASE265/p/12264501.html