java理論基礎(chǔ)Stream API終端操作示例解析
一、Java Stream管道數(shù)據(jù)處理操作
在本號之前寫過的文章中,曾經(jīng)給大家介紹過 Java Stream管道流是用于簡化集合類元素處理的java API。在使用的過程中分為三個階段。在開始本文之前,我覺得仍然需要給一些新朋友介紹一下這三個階段,如圖:
- 第一階段(圖中藍(lán)色):將集合、數(shù)組、或行文本文件轉(zhuǎn)換為java Stream管道流
- 第二階段(圖中虛線部分):管道流式數(shù)據(jù)處理操作,處理管道中的每一個元素。上一個管道中的輸出元素作為下一個管道的輸入元素。
- 第三階段(圖中綠色):管道流結(jié)果處理操作,也就是本文的將介紹的核心內(nèi)容。
在開始學(xué)習(xí)之前,仍然有必要回顧一下我們之前給大家講過的一個例子:
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轉(zhuǎn)換為管道流Stream
然后進(jìn)行管道數(shù)據(jù)處理操作,先用fliter函數(shù)過濾所有大寫L開頭的字符串,然后將管道中的字符串轉(zhuǎn)換為大寫字母toUpperCase,然后調(diào)用sorted方法排序。這些API的用法在本號之前的文章有介紹過。其中還使用到了lambda表達(dá)式和函數(shù)引用。
最后使用collect函數(shù)進(jìn)行結(jié)果處理,將java Stream管道流轉(zhuǎn)換為List。最終list的輸出結(jié)果是:[LEMUR, LION]
如果你不使用java Stream管道流的話,想一想你需要多少行代碼完成上面的功能呢?回到正題,這篇文章就是要給大家介紹第三階段:對管道流處理結(jié)果都可以做哪些操作呢?下面開始吧!
二、ForEach和ForEachOrdered
如果我們只是希望將Stream管道流的處理結(jié)果打印出來,而不是進(jìn)行類型轉(zhuǎn)換,我們就可以使用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()函數(shù)表示對管道中的元素進(jìn)行并行處理,而不是串行處理,這樣處理速度更快。但是這樣就有可能導(dǎo)致管道流中后面的元素先處理,前面的元素后處理,也就是元素的順序無法保證
forEachOrdered從名字上看就可以理解,雖然在數(shù)據(jù)處理順序上可能無法保障,但是forEachOrdered方法可以在元素輸出的順序上保證與元素進(jìn)入管道流的順序一致。也就是下面的樣子(forEach方法則無法保證這個順序):
Monkey
Lion
Giraffe
Lemur
Lion
三、元素的收集collect
java Stream 最常見的用法就是:一將集合類轉(zhuǎn)換成管道流,二對管道流數(shù)據(jù)處理,三將管道流處理結(jié)果在轉(zhuǎn)換成集合類。那么collect()方法就為我們提供了這樣的功能:將管道流處理結(jié)果在轉(zhuǎn)換成集合類。
3.1.收集為Set
通過Collectors.toSet()方法收集Stream的處理結(jié)果,將所有元素收集到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", "Lion" ).collect(Collectors.toList()); // 最終collectToList中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
3.3.通用的收集方式
上面為大家介紹的元素收集方式,都是專用的。比如使用Collectors.toSet()收集為Set類型集合;使用Collectors.toList()收集為List類型集合。那么,有沒有一種比較通用的數(shù)據(jù)元素收集方式,將數(shù)據(jù)收集為任意的Collection接口子類型。 所以,這里就像大家介紹一種通用的元素收集方式,你可以將數(shù)據(jù)元素收集到任意的Collection類型:即向所需Collection類型提供構(gòu)造函數(shù)的方式。
LinkedList<String> collectToCollection = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ).collect(Collectors.toCollection(LinkedList::new)); //最終collectToCollection中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
注意:代碼中使用了LinkedList::new,實(shí)際是調(diào)用LinkedList的構(gòu)造函數(shù),將元素收集到Linked List。當(dāng)然你還可以使用諸如LinkedHashSet::new
和PriorityQueue::new
將數(shù)據(jù)元素收集為其他的集合類型,這樣就比較通用了。
3.4.收集到Array
通過toArray(String[]::new)方法收集Stream的處理結(jié)果,將所有元素收集到字符串?dāng)?shù)組中。
String[] toArray = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .toArray(String[]::new); //最終toArray字符串?dāng)?shù)組中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
3.5.收集到Map
使用Collectors.toMap()方法將數(shù)據(jù)元素收集到Map里面,但是出現(xiàn)一個問題:那就是管道中的元素是作為key,還是作為value。我們用到了一個Function.identity()方法,該方法很簡單就是返回一個“ t -> t ”(輸入就是輸出的lambda表達(dá)式)。另外使用管道流處理函數(shù)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()// 輸入元素的不同的字母個數(shù),作為value )); // 最終toMap的結(jié)果是: {Monkey=6, Lion=4, Lemur=5, Giraffe=6}
3.6.分組收集groupingBy
Collectors.groupingBy用來實(shí)現(xiàn)元素的分組收集,下面的代碼演示如何根據(jù)首字母將不同的數(shù)據(jù)元素收集到不同的List,并封裝為Map。
Map<Character, List<String>> groupingByList = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .collect(Collectors.groupingBy( s -> s.charAt(0) , //根據(jù)元素首字母分組,相同的在一組 // counting() // 加上這一行代碼可以實(shí)現(xiàn)分組統(tǒng)計(jì) )); // 最終groupingByList內(nèi)的元素: {G=[Giraffe], L=[Lion, Lemur, Lion], M=[Monkey]} //如果加上counting() ,結(jié)果是: {G=1, L=3, M=1}
這是該過程的說明:groupingBy第一個參數(shù)作為分組條件,第二個參數(shù)是子收集器。
四、其他常用方法
boolean containsTwo = IntStream.of(1, 2, 3).anyMatch(i -> i == 2); // 判斷管道中是否包含2,結(jié)果是: true long nrOfAnimals = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur" ).count(); // 管道中元素數(shù)據(jù)總計(jì)結(jié)果nrOfAnimals: 4 int sum = IntStream.of(1, 2, 3).sum(); // 管道中元素數(shù)據(jù)累加結(jié)果sum: 6 OptionalDouble average = IntStream.of(1, 2, 3).average(); //管道中元素數(shù)據(jù)平均值average: OptionalDouble[2.0] int max = IntStream.of(1, 2, 3).max().orElse(0); //管道中元素數(shù)據(jù)最大值max: 3 IntSummaryStatistics statistics = IntStream.of(1, 2, 3).summaryStatistics(); // 全面的統(tǒng)計(jì)結(jié)果statistics: IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}
以上就是java理論基礎(chǔ)Stream API終端操作示例解析的詳細(xì)內(nèi)容,更多關(guān)于java Stream API終端操作的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot整合screw實(shí)現(xiàn)自動生成數(shù)據(jù)庫設(shè)計(jì)文檔
使用navicat工作的話,導(dǎo)出的格式是excel不符合格式,還得自己整理。所以本文將用screw工具包,整合到springboot的項(xiàng)目中便可以自動生成數(shù)據(jù)庫設(shè)計(jì)文檔,非常方便,下面就分享一下教程2022-11-11form-data與x-www-form-urlencoded的區(qū)別以及知識延伸
這篇文章主要給大家介紹了關(guān)于form-data與x-www-form-urlencoded的區(qū)別以及知識延伸,form-data和x-www-form-urlencoded都是HTTP請求中用于傳輸表單數(shù)據(jù)的編碼格式,需要的朋友可以參考下2023-11-11SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解
這篇文章主要介紹了SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06intellij idea 2021.2 打包并上傳運(yùn)行spring boot項(xiàng)目的詳細(xì)過程(spring boot 2
這篇文章主要介紹了intellij idea 2021.2 打包并上傳運(yùn)行一個spring boot項(xiàng)目(spring boot 2.5.4),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼
延時隊(duì)列場景在我們?nèi)粘I(yè)務(wù)開發(fā)中經(jīng)常遇到,它是一種特殊類型的消息隊(duì)列,本文就來介紹一下SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-02-02SpringMVC @RequestMapping注解應(yīng)用方法示例講解
通過@RequestMapping注解可以定義不同的處理器映射規(guī)則,下面這篇文章主要給大家介紹了關(guān)于SpringMVC中@RequestMapping注解用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Java?MyBatis是如何執(zhí)行一條SQL語句的
這篇文章主要介紹了Java?MyBatis是如何執(zhí)行一條SQL語句的,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07SpringBoot整合Servlet和Filter和Listener組件詳解
這篇文章主要介紹了SpringBoot整合Servlet和Filter和Listener組件詳解,在整合某報表插件時就需要使用Servlet,Spring Boot中對于整合這些基本的Web組件也提供了很好的支持,需要的朋友可以參考下2024-01-01