流提供了一种 可以让我们子可以在比集合更高的概念级别上指定计算的数据视图.通过使用流,我们可以说明想要完成什么任务,而不是说明如何去完成它.我们将操作的调度留给具体实现去解决
从迭代到流的操作
在处理集合时,我们通常会迭代遍历他的元素,并且在每个元素上执行某项操作.
例如
long count = 0;
for(String w : words){
if(w.length() > 12) {
count++;
}
}
在使用流时,同样的操作看起来像下面这样
long count = words.stream().filter(w -> w.length() >12).count();流的版本比循环版本更加易于阅读,因为我们不必扫描整个代码去查找过滤和计数操作,方法名就可以直接告诉我们其代码意欲何为.而且循环需要非常详细的指定操作的顺序,而流却能够直接告诉我们其代码意欲何为.而且循环需要非常详细的指定操作的顺序,而流却可以以其想要的任何方式来调度这些操作,只要结果是正确的即可.
流遵循了做什么而非怎么做的原则,流和集合的差异如下
- 流并不存储元素
留的操作不会修改其数据源
流的操作是尽可能惰性执行的
三阶段操作管道如下:
下面是用到的api
- Stream filter(Predicate<? super T> p) 产生一个流,其中包括当前流中满足P的所有元素
- long count(): 产生当前流中元素的数量.这是一个终止操作
- default Stream stream()
- default Stream parallelStream(): 产生当前集合中所有元素的顺序流或者并行流
filter,map和flatMap方法
流的转换会产生一个新流,他的元素派生自另一个流中的元素.我们已经看到了filter转换会产生一个流,他的元素与某种条件相互匹配.下面,我们将一个字符串流转换为只包含长单词的另一个流:
List<String> wordList = ....;Stream<String> longWords = wordList.stream().filter(w -> w.length() > 12);
filter的引元是Predicate,即从T到boolean的函数
通常我们想要按照某种方式来转换流中的值,此时可以使用map方法并传递执行该转换的函数.例如,我们可以像下面这样将所有的单词都转换为小写:
这里我们使用的是带有方法引用的map,但是通常我们可以使用lambda表达式来替代
Stream<String> firstLetters = words.stream().map(s->s.substring(0,1));上面语句所产生的流中包含了所有单词的首字母
在使用map时,会有一个函数应用到每个元素上,并且其结果是包含了应用该函数后所产生的所有结果的流.
一下是api:
- Stream filtr(Predicate<? super T> predicate) 产生一个流,它包含当前流中所有满足断言条件的元素
- Stream map(Function<? super T, ? extends R> mapper): 产生一个流,他包含将mappr应用于当前流中所有元素所产生的结果
流的排序
对于流的排序,有多种sorted方法的变体可用.其中一种用于操作Comparable元素的流,而另一种可以接受一个Comparator.下面我们对字符串排序,使得最长的字符串排在最前面
Stream<String> longestFirst = words.stream().sorted(Comparator.comparing(String::length).reversed);api:
- Stream sorted(Comparator<? super T> comparator): 产生一个流,他的元素是当前流中所有元素按照顺序排列的.
收集结果
针对流中的元素收集到另一个目标中,有一个便捷方法collect可用,他会接受一个Collector接口的实例.Collectors类提供了大量用于生成公共收集器的工厂方法.
假设想要通过连接操作来收集流中的所有字符串.我们可以调用:
如果想要在元素之前增加间隔符,可以将间隔符传递给joining方法
String result = stream.collect(Collectors.joining(", "));最后的应用
System.out.println(Arrays.stream(clusters).map(DocumentCluster::getDocumentCount)
.sorted(Comparator.reverseOrder())
.map(Objects::toString)
.collect(Collectors.joining(", ", "Cluster sizes: ", "")));