在本號以前寫過的文章中,曾經給你們介紹過 Java Stream管道流是用於簡化集合類元素處理的java API。在使用的過程當中分爲三個階段。在開始本文以前,我以爲仍然須要給一些新朋友介紹一下這三個階段,如圖:java
在開始學習以前,仍然有必要回顧一下咱們以前給你們講過的一個例子:spring
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);
[LEMUR, LION]
若是你不使用java Stream管道流的話,想想你須要多少行代碼完成上面的功能呢?回到正題,這篇文章就是要給你們介紹第三階段:對管道流處理結果均可以作哪些操做呢?下面開始吧!編程
若是咱們只是但願將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);
Monkey Lion Giraffe Lemur Lion
java Stream 最多見的用法就是:一將集合類轉換成管道流,二對管道流數據處理,三將管道流處理結果在轉換成集合類。那麼collect()方法就爲咱們提供了這樣的功能:將管道流處理結果在轉換成集合類。springboot
經過Collectors.toSet()方法收集Stream的處理結果,將全部元素收集到Set集合中。ide
Set<String> collectToSet = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .collect(Collectors.toSet()); //最終collectToSet 中的元素是:[Monkey, Lion, Giraffe, Lemur],注意Set會去重。
一樣,能夠將元素收集到List
使用toList()
收集器中。函數式編程
List<String> collectToList = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ).collect(Collectors.toList()); // 最終collectToList中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
上面爲你們介紹的元素收集方式,都是專用的。好比使用Collectors.toSet()收集爲Set類型集合;使用Collectors.toList()收集爲List類型集合。那麼,有沒有一種比較通用的數據元素收集方式,將數據收集爲任意的Collection接口子類型。
因此,這裏就像你們介紹一種通用的元素收集方式,你能夠將數據元素收集到任意的Collection類型:即向所需Collection類型提供構造函數的方式。函數
LinkedList<String> collectToCollection = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ).collect(Collectors.toCollection(LinkedList::new)); //最終collectToCollection中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
注意:代碼中使用了LinkedList::new,實際是調用LinkedList的構造函數,將元素收集到Linked List。固然你還可使用諸如LinkedHashSet::new
和PriorityQueue::new
將數據元素收集爲其餘的集合類型,這樣就比較通用了。學習
經過toArray(String[]::new)方法收集Stream的處理結果,將全部元素收集到字符串數組中。code
String[] toArray = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .toArray(String[]::new); //最終toArray字符串數組中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
使用Collectors.toMap()方法將數據元素收集到Map裏面,可是出現一個問題:那就是管道中的元素是做爲key,仍是做爲value。咱們用到了一個Function.identity()方法,該方法很簡單就是返回一個「 t -> t 」(輸入就是輸出的lambda表達式)。另外使用管道流處理函數distinct()
來確保Map鍵值的惟一性。
Map<String, Integer> toMap = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .distinct() .collect(Collectors.toMap( Function.identity(), //元素輸入就是輸出,做爲key s -> (int) s.chars().distinct().count()// 輸入元素的不一樣的字母個數,做爲value )); // 最終toMap的結果是: {Monkey=6, Lion=4, Lemur=5, Giraffe=6}
Collectors.groupingBy用來實現元素的分組收集,下面的代碼演示如何根據首字母將不一樣的數據元素收集到不一樣的List,並封裝爲Map。
Map<Character, List<String>> groupingByList = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .collect(Collectors.groupingBy( s -> s.charAt(0) , //根據元素首字母分組,相同的在一組 // counting() // 加上這一行代碼能夠實現分組統計 )); // 最終groupingByList內的元素: {G=[Giraffe], L=[Lion, Lemur, Lion], M=[Monkey]} //若是加上counting() ,結果是: {G=1, L=3, M=1}
這是該過程的說明:groupingBy第一個參數做爲分組條件,第二個參數是子收集器。
boolean containsTwo = IntStream.of(1, 2, 3).anyMatch(i -> i == 2); // 判斷管道中是否包含2,結果是: true long nrOfAnimals = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur" ).count(); // 管道中元素數據總計結果nrOfAnimals: 4 int sum = IntStream.of(1, 2, 3).sum(); // 管道中元素數據累加結果sum: 6 OptionalDouble average = IntStream.of(1, 2, 3).average(); //管道中元素數據平均值average: OptionalDouble[2.0] int max = IntStream.of(1, 2, 3).max().orElse(0); //管道中元素數據最大值max: 3 IntSummaryStatistics statistics = IntStream.of(1, 2, 3).summaryStatistics(); // 全面的統計結果statistics: IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}