前言
專注于為中小企業(yè)提供成都網(wǎng)站制作、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)日土免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
只有光頭才能變強。
相信也有不少的同學(xué)想要知道:Lambda表達(dá)式在工作中哪個場景會用得比較多?跟Lambda搭邊的,使用 Stream流會比較多
一般人第一次看Stream流的代碼,都會有點看不懂(它的代碼看起來好像就不是寫Java一樣.),希望這篇文章能帶大家入個門
一、體驗Stream流
大家在自學(xué)時,大多數(shù)會學(xué)過一個程序:算出從數(shù)組元素的和,當(dāng)時我們是怎么寫的?一般來說是這樣的:
publicstaticvoidmain(String[]args){int[]nums={1,2,3};intsum=0;for(inti:nums){sum+=i;}System.out.println("結(jié)果為:"+sum);}
如果我們使用Stream流的話,可以這樣:
publicstaticvoidmain(String[]args){int[]nums={1,2,3};intsum2=IntStream.of(nums).sum();System.out.println("結(jié)果為:"+sum2);}
從 代碼量上可以明顯看出,用Stream流的方式會少一些。
我理解的Stream流編程就是: 某些場景會經(jīng)常用到操作(求和/去重/過濾….等等),已經(jīng)封裝好API給你了,你自己別寫了,調(diào)我給你提供的API就好了。
1.1 支持并發(fā)
回到我們最原始的代碼:
publicstaticvoidmain(String[]args){int[]nums={1,2,3};intsum=0;for(inti:nums){sum+=i;}System.out.println("結(jié)果為:"+sum);}
如果我們想要for循環(huán)的內(nèi)部支持并發(fā)的話,顯然不太好去寫。但使用Stream流的方式, 調(diào)用一個方法就可以支持并發(fā)(parallel):
publicstaticvoidmain(String[]args){int[]nums={1,2,3};intsum2=IntStream.of(nums).parallel().sum();System.out.println("結(jié)果為:"+sum2);}
優(yōu)點:調(diào)API肯定是比自己寫的代碼量要少。
缺點:不方便調(diào)試
為什么要使用Stream流在我看來就是以上兩個原因:
二、如何使用Stream流?
Stream繼承結(jié)構(gòu)圖
使用Stream流分為三步:
三步走
2.1 創(chuàng)建流
創(chuàng)建流我們最常用的就是 從集合中創(chuàng)建出流
/***返回的都是流對象*@paramargs*/publicstaticvoidmain(String[]args){Listlist=newArrayList<>();//從集合創(chuàng)建Stream stream=list.stream();Stream stream1=list.parallelStream();//從數(shù)組創(chuàng)建IntStreamstream2=Arrays.stream(newint[]{2,3,5});//創(chuàng)建數(shù)字流IntStreamintStream=IntStream.of(1,2,3);//使用random創(chuàng)建IntStreamlimit=newRandom().ints().limit(10);}
2.2 執(zhí)行中間操作
怎么理解中間操作?意思是這樣的:在上面我們已經(jīng)能創(chuàng)建出Stream了,我們是對 Stream進(jìn)行操作,對Stream操作返回完返回的還是Stream,那么我們稱這個操作為中間操作。
中間操作 解釋
比如,我們現(xiàn)在有個字符串my name is 007,代碼如下:
Stringstr="mynameis007";Stream.of(str.split("")).filter(s->s.length()>2).map(s->s.length()).forEach(System.out::println);
分解:
1、從字符串?dāng)?shù)組創(chuàng)建出流對象:
Streamsplit=Stream.of(str.split(""));
2、通過流對象的API執(zhí)行中間操作(filter),返回的還是流對象:
StreamfilterStream=split.filter(s->s.length()>2);
3、通過返回的流對象再執(zhí)行中間操作(map),返回的還是流對象:
StreamintegerStream=filterStream.map(s->s.length());
因為中間操作返回的都是 流對象,所以我們可以 鏈?zhǔn)秸{(diào)用。
注意:Stream上的操作并不會立即執(zhí)行,只有等到用戶真正需要結(jié)果的時候才會執(zhí)行( 惰性求值)。
比如說,peek()是一個中間操作,返回的是Stream流對象,只要它不執(zhí)行最終的操作,這個Stream是不會執(zhí)行的。
Stringstr="mynameis007";Stream.of(str.split("")).peek(System.out::println);//不會有信息打印
2.3 執(zhí)行最終操作
最終操作返回的不再是Stream對象, 調(diào)用了最終操作的方法,Stream才會執(zhí)行。還是以上面的例子為例:
Stringstr="mynameis007";Stream.of(str.split("")).peek(System.out::println).forEach(System.out::println)
這次我們加入了最終操作,所以這次的Stream流會被執(zhí)行,由于中間操作和最終操作都是執(zhí)行打印,所以會看到兩次打印:
結(jié)果圖
至于中間操作和最終操作怎么區(qū)分,我們以 返回值來看就行了。中間操作返回的是Stream實例對象,最終操作返回的不是Stream實例對象:
Stream接口的方法
最后
這篇文章主要跟大家一起初步認(rèn)識一下Stream流,至于中間操作、最終操作的API講解我就不寫了(網(wǎng)上的教程也很多)
使用Stream的原因我認(rèn)為有兩個: