在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API。在使用的过程中分为三个阶段。在开始本文之前,我觉得仍然需要给一些新朋友介绍一下这三个阶段,如图:

Java Stream函数式编程?用过都说好,案例图文详解送给你

  • 第一阶段(图中蓝色):将集合、数组、或行文本文件转换为java Stream管道流
  • 第二阶段(图中虚线部分):管道流式数据处理操作,处理管道中的每一个元素。上一个管道中的输出元素作为下一个管道的输入元素。
  • 第三阶段(图中绿色):管道流结果处理操作,也就是本文的将介绍的核心内容。

在开始学习之前,仍然有必要回顾一下我们之前给大家讲过的一个例子:

 List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");  List<String> list = nameStrs.stream()         .filter(s -> s.startsWith("L"))         .map(String::toUpperCase)         .sorted()         .collect(toList()); System.out.println(list);
  • 首先使用stream()方法将字符串List转换为管道流Stream
  • 然后进行管道数据处理操作,先用fliter函数过滤所有大写L开头的字符串,然后将管道中的字符串转换为大写字母toUpperCase,然后调用sorted方法排序。这些API的用法在本号之前的文章有介绍过。其中还使用到了lambda表达式和函数引用。
  • 最后使用collect函数进行结果处理,将java Stream管道流转换为List。最终list的输出结果是:[LEMUR, LION]

如果你不使用java Stream管道流的话,想一想你需要多少行代码完成上面的功能呢?回到正题,这篇文章就是要给大家介绍第三阶段:对管道流处理结果都可以做哪些操作呢?下面开始吧!

二、ForEach和ForEachOrdered

如果我们只是希望将Stream管道流的处理结果打印出来,而不是进行类型转换,我们就可以使用forEach()方法或forEachOrdered()方法。

 Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")         .parallel()         .forEach(System.out::println); Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")         .parallel()         .forEachOrdered(System.out::println);
  • parallel()函数表示对管道中的元素进行并行处理,而不是串行处理,这样处理速度更快。但是这样就有可能导致管道流中后面的元素先处理,前面的元素后处理,也就是元素的顺序无法保证
  • forEachOrdered从名字上看就可以理解,虽然在数据处理顺序上可能无法保障,但是forEachOrdered方法可以在元素输出的顺序上保证与元素进入管道流的顺序一致。也就是下面的样子(forEach方法则无法保证这个顺序):
Monkey Lion Giraffe Lemur Lion

三、元素的收集collect

java Stream 最常见的用法就是:一将集合类转换成管道流,二对管道流数据处理,三将管道流处理结果在转换成集合类。那么collect()方法就为我们提供了这样的功能:将管道流处理结果在转换成集合类。

3.1.收集为Set

通过Collectors.toSet()方法收集Stream的处理结果,将所有元素收集到Set集合中。

 Set<String> collectToSet = Stream.of(    "Monkey", "Lion", "Giraffe", "Lemur", "Lion" )  .collect(Collectors.toSet());  //最终collectToSet 中的元素是:[Monkey, Lion, Giraffe, Lemur],注意Set会去重。

3.2.收集到List

同样,可以将元素收集到List使用toList()收集器中。

 List<String> collectToList = Stream.of(    "Monkey", "Lion", "Giraffe", "Lemur",