Java8 Stream流總結(jié)整理

1. 新時(shí)代的Java語言

新時(shí)代的Java是以JDK8的發(fā)布為分水嶺树瞭,從JDK8開始,Java開發(fā)進(jìn)入一個(gè)新的階段典徊,Java8 經(jīng)歷9個(gè)里程碑版本颤专,于2014年3月18日正式發(fā)布,距今已有很長一段時(shí)間了逮光,一些流行框架都采用了Java8代箭,比如Mybatis3.5.x開始全面采用JDK8,Spring5.x開始全面采用JDK8涕刚,SpringBoot2.x開始全面采用JDK8嗡综,Spring Cloud F版開始也要求至少JDK8;

2. Java8有哪些新特性副女?

1蛤高、Lambda表達(dá)式蚣旱;

2、方法引用戴陡;

3塞绿、默認(rèn)方法;

4恤批、可重復(fù)注解异吻;

5、類型注解喜庞;

6诀浪、改進(jìn)的類型推斷;

7延都、方法參數(shù)反射雷猪;

8、Stream API晰房;

9求摇、Security增強(qiáng);

10殊者、JavaFX增強(qiáng)与境;

11、Tool增強(qiáng)猖吴;

12摔刁、國際化增強(qiáng);

13海蔽、Deployment增強(qiáng)共屈;

14、date-time日期包党窜;

15趁俊、Nashorn javascript引擎;

16刑然、Pack200壓縮工具寺擂;

17、IO and NIO增強(qiáng)泼掠;

18怔软、java.lang and java.util 包增強(qiáng);

19择镇、JDBC 4.2增強(qiáng)挡逼;

20、Java DB腻豌;

21家坎、java.net包增強(qiáng)嘱能;

22、java.util.concurrent包增強(qiáng)虱疏;

23惹骂、Java XML - JAXP;

24做瞪、HotSpot增強(qiáng)对粪;

25、Java Mission Control装蓬;

在Java8中最重要的兩個(gè)新特性就要數(shù)Lambda表達(dá)式和Stream API了著拭;

3. Stream API

Stream是Java 8中引入的全新API,位于java.util.stream包下牍帚,它與java.io 包下的 InputStream 和 OutputStream 等輸入輸出流是完全不同的概念儡遮;

Java 8 中的 Stream 是對數(shù)組、集合(Collection)功能的增強(qiáng)暗赶,它專注于對集合對象進(jìn)行各種非常便利且高效的操作峦萎,它的底層實(shí)現(xiàn)使用了并行化操作,利用Java7 中引入的 Fork/Join 框架來拆分任務(wù)忆首,加速處理過程,充分利用了現(xiàn)在多核處理器的優(yōu)勢被环;

需要強(qiáng)調(diào)的是Stream不對任何數(shù)據(jù)進(jìn)行存儲糙及,所以Stream也不是數(shù)據(jù)結(jié)構(gòu),Stream實(shí)現(xiàn)的是快速地對集合類的數(shù)據(jù)源進(jìn)行操作(如:過濾筛欢,排序浸锨、求和等等);

Stream

IntStream

DoubleStream

LongStream

Stream出現(xiàn)之前版姑,遍歷一個(gè)集合List柱搜、Array最傳統(tǒng)的做法大概是用Iterator,或者 for 循環(huán)剥险,這種兩種方式都屬于外部迭代聪蘸,然而外部迭代存在著一些問題;

1表制、開發(fā)人員需要自己手寫迭代的邏輯健爬,大部分場景迭代邏輯都是每個(gè)元素遍歷一次;

2么介、如果存在像排序娜遵、求最小值、求最大值這樣的有狀態(tài)的中間操作壤短,不得不進(jìn)行多次迭代设拟;

Stream 處理數(shù)據(jù)的過程可以類別成工廠的流水線慨仿,數(shù)據(jù)可以看做流水線上的原料,對數(shù)據(jù)的操作可以看做流水線上的工人對原料的操作纳胧;

事實(shí)上Stream 只是一個(gè)接口镰吆,并沒有操作的缺省實(shí)現(xiàn),最主要的實(shí)現(xiàn)是

ReferencePipeline躲雅,而 ReferencePipeline 繼承自AbstractPipeline鼎姊,AbstractPipeline實(shí)現(xiàn)了BaseStream 接口并實(shí)現(xiàn)了它的方法,但ReferencePipeline 仍然是一個(gè)抽象類相赁,因?yàn)樗]有實(shí)現(xiàn)所有的抽象方法相寇,比如 AbstractPipeline 中的 opWrapSink,ReferencePipeline內(nèi)部定義了三個(gè)靜態(tài)內(nèi)部類钮科,分別是:Head, StatelessOp, StatefulOp唤衫,但只有 Head 不再是抽象類;

ReferencePipeline 包含了控制數(shù)據(jù)流入的 Head绵脯,中間操作 StatelessOp, StatefulOp佳励,終止操作 TerminalOp;


Stream的工作流程

在Java 8中蛆挫,Stream的生命周期一共有三個(gè)階段:

1.獲取數(shù)據(jù)源并創(chuàng)建Stream實(shí)例赃承,數(shù)據(jù)源可以是數(shù)組、列表悴侵、對象或者I/O流瞧剖;

2.執(zhí)行中間操作(Intermediate Operations),中間操作可以是過濾可免、排序抓于、類型轉(zhuǎn)換等操作;

3.執(zhí)行末端操作(Terminal Operation)浇借,末端操作主要是對最終結(jié)果進(jìn)行計(jì)數(shù)捉撮、求和、創(chuàng)建新集合等操作妇垢;

Stream的操作大部分都是鏈?zhǔn)讲僮鳎?/p>


如何創(chuàng)建Stream實(shí)例巾遭?

1.使用數(shù)組創(chuàng)建Stream

2.使用List集合創(chuàng)建Stream

3.使用Builder方法創(chuàng)建Stream

參看代碼演示;

Stream 常用的流操作包括:

中間操作(Intermediate Operations)

Stream的中間操作將返回一個(gè)Stream,它允許開發(fā)者以查詢的方式調(diào)用多個(gè)其他的操作闯估。特別注意的是恢总,在“終端操作”方法未被調(diào)用之前,“中間操作”的方法不會被執(zhí)行睬愤;

無狀態(tài)(Stateless)操作:每個(gè)數(shù)據(jù)的處理是獨(dú)立的片仿,不會影響或依賴之前的數(shù)據(jù)。如filter()尤辱、flatMap()砂豌、flatMapToDouble()厢岂、flatMapToInt()、flatMapToLong()阳距、map()塔粒、mapToDouble()、mapToInt()筐摘、mapToLong()卒茬、peek()、unordered() 等咖熟;

有狀態(tài)(Stateful)操作:處理時(shí)會記錄狀態(tài)圃酵,比如處理了幾個(gè)。后面元素的處理會依賴前面記錄的狀態(tài)馍管,或者拿到所有元素才能繼續(xù)下去郭赐,如

distinct()、sorted()确沸、sorted(comparator)捌锭、limit()、skip() 等罗捎;

終止操作(Terminal Operations)

非短路操作:處理完所有數(shù)據(jù)才能得到結(jié)果观谦,如

collect()、count()桨菜、forEach()豁状、forEachOrdered()、max()雷激、min()、reduce()告私、toArray()等屎暇;

短路(short-circuiting)操作:拿到符合預(yù)期的結(jié)果就會停下來,不一定會處理完所有數(shù)據(jù)驻粟。如anyMatch()根悼、allMatch()、noneMatch()蜀撑、findFirst()挤巡、findAny() 等;


Parallel Streams

streams可以是串行或者并行的酷麦;

在串行streams上的操作是在一個(gè)單線程中完成的矿卑,而并行streams上的操作是在多個(gè)線程上并發(fā)完成的;

使用并行stream可以充分利用多核處理器的優(yōu)勢沃饶,提升速度和性能母廷,而所需要做的僅僅是將stream() 改為 parallelStream()即可轻黑;

為什么要使用Stream?

在命令式編程中,我們必須逐行編寫代碼琴昆,才能完成相關(guān)的計(jì)算氓鄙,例如,計(jì)算1~10000的數(shù)的總和业舍,我們需要使用for(int i=1;i<=10000;i++){….}循環(huán)語句來迭代求值抖拦,在這個(gè)語句中,我們需要花費(fèi)額外的精力來維護(hù)loop變量的值舷暮,而在聲明式編程中态罪,我們只需要關(guān)注想要實(shí)現(xiàn)的目標(biāo),而不是其內(nèi)部重復(fù)的循環(huán)邏輯脚牍;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末向臀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诸狭,更是在濱河造成了極大的恐慌券膀,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驯遇,死亡現(xiàn)場離奇詭異芹彬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)叉庐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門舒帮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陡叠,你說我怎么就攤上這事玩郊。” “怎么了枉阵?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵译红,是天一觀的道長。 經(jīng)常有香客問我兴溜,道長侦厚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任拙徽,我火速辦了婚禮刨沦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膘怕。我一直安慰自己想诅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侧蘸,像睡著了一般裁眯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讳癌,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天穿稳,我揣著相機(jī)與錄音,去河邊找鬼晌坤。 笑死逢艘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的骤菠。 我是一名探鬼主播它改,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼商乎!你這毒婦竟也來了央拖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鹉戚,失蹤者是張志新(化名)和其女友劉穎鲜戒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抹凳,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遏餐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赢底。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片失都。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幸冻,靈堂內(nèi)的尸體忽然破棺而出粹庞,到底是詐尸還是另有隱情,我是刑警寧澤洽损,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布庞溜,位于F島的核電站,受9級特大地震影響趁啸,放射性物質(zhì)發(fā)生泄漏强缘。R本人自食惡果不足惜督惰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一不傅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赏胚,春花似錦访娶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秘车。三九已至,卻和暖如春劫哼,著一層夾襖步出監(jiān)牢的瞬間叮趴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工权烧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眯亦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓般码,卻偏偏與公主長得像妻率,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子板祝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355