当前位置 : 主页 > 编程语言 > java >

Java的流库-stream的几个方法

来源:互联网 收集:自由互联 发布时间:2022-07-13
流提供了一种 可以让我们子可以在比集合更高的概念级别上指定计算的数据视图.通过使用流,我们可以说明想要完成什么任务,而不是说明如何去完成它.我们将操作的调度留给具体实现


流提供了一种 可以让我们子可以在比集合更高的概念级别上指定计算的数据视图.通过使用流,我们可以说明想要完成什么任务,而不是说明如何去完成它.我们将操作的调度留给具体实现去解决

从迭代到流的操作

在处理集合时,我们通常会迭代遍历他的元素,并且在每个元素上执行某项操作.
例如

List<String> words = new ArrayList<>();
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方法并传递执行该转换的函数.例如,我们可以像下面这样将所有的单词都转换为小写:

    Stream<String> longWords = wordList.stream().map(String::toLowerCase);

    这里我们使用的是带有方法引用的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类提供了大量用于生成公共收集器的工厂方法.
    假设想要通过连接操作来收集流中的所有字符串.我们可以调用:

    String result = stream.collect(Collectors.joining());

    如果想要在元素之前增加间隔符,可以将间隔符传递给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: ", "")));


    网友评论