重走Java基礎(chǔ)之Streams(一)

作者:知秋
來源:重走Java基礎(chǔ)之Streams(一)


因為經(jīng)常逛stackoverflow,最近也在看reactive和storm以及前一陣子也用流式ORM框架speedmentSpringboot整合改造了migo2.0中的單點登錄,深深的感受到j(luò)ava8已經(jīng)融入我們很深了憔辫,尤其是Spring5對其進行大力支持,覺得有必要再對自己的知識整理一下慧邮,順帶就把stackoverflow一些東西自己拿過來整理翻譯一下,里面也會加入一些自己的理解

Introduction

流表示一系列元素并支持不同類型的操作來對這些元素執(zhí)行計算。在Java 8中,Collection接口有兩種方法來生成Stream

  • 1)stream()和
  • 2) parallelStream()

流操作包括中間或終端。 中間操作返回一個流拉鹃,所以我們可以鏈接多個中間操作而不使用分號辈赋。 終端操作是void的或返回非流結(jié)果。

Examples

Using Streams

A Stream是可以執(zhí)行順序和并行聚合操作的一系列元素 膏燕。 任何給定的“Stream”都可能有無限量的數(shù)據(jù)流過它钥屈。 你所得到的結(jié)果是從“Stream”接收的數(shù)據(jù)在到達時被單獨處理,而不是完全對數(shù)據(jù)執(zhí)行批處理坝辫。 當與lambda表達式 結(jié)合時篷就,它們提供了使用函數(shù)方法對數(shù)據(jù)序列執(zhí)行操作的簡明方法。

Example: (see it work on Ideone)

Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");

fruitStream.filter(s -> s.contains("a"))
           .map(String::toUpperCase)
           .sorted()
           .forEach(System.out::println);

Output:

APPLE
BANANA
ORANGE
PEAR

上述代碼執(zhí)行的操作可以總結(jié)如下:

  1. 使用靜態(tài)工廠方法Stream.of(values)創(chuàng)建一個包含fruit String的順序排序StreamStream 元素

  2. filter()操作僅保留與給定謂詞(由謂詞返回true測試時的元素)匹配的元素近忙。 在這種情況下竭业,它保留含有“a”的元素智润。 謂詞作為lambda表達式給出。

  3. map() 操作轉(zhuǎn)換 每個元素使用給定的函數(shù)未辆,稱為映射器窟绷。 在這種情況下,每個fruit String使用method-reference映射到將string字符串轉(zhuǎn)換為大寫版本String::toUppercase咐柜。

    Note 如果映射函數(shù)返回與其輸入?yún)?shù)不同的類型兼蜈,那么map()操作將返回具有不同泛型類型的流。 例如在一個Stream調(diào)用.map(String :: isEmpty)返回一個Stream<Boolean>

  4. sorted()操作對Stream的元素進行排序 根據(jù)它們的自然排序(根據(jù)在'String'的情況下對所在字典的順序拙友,其實都知道)为狸。

  5. 最后, forEach(action) 操作執(zhí)行一個動作遗契,作用于“Stream”的每個元素辐棒,將其傳遞給一個 Consumer。 在該示例中姊途,每個元素只是被打印到控制臺涉瘾。 該操作是終端操作,因此不可能再次進行操作捷兰。

  6. NoteStream中定義的操作之所以被執(zhí)行立叛,是因為最后有終端操作。 假如沒有終端操作贡茅,'Stream'將不被處理秘蛇,因為'Stream'輸出不被任何終端操作使用(省的浪費計算資源,所以很多書上稱之為被動式foreach)顶考。

Chained operations

操作(如上所示)鏈接在一起以形成可以被視為對數(shù)據(jù)的查詢


Reusing Streams

一個Stream不能重復使用赁还。 一旦調(diào)用任何中間或終端操作,“Stream”對象將變得不可用驹沿。 Stream代替地使用中間Stream對象以便將中間操作鏈接在一起通過一系列Stream操作來生成一個Stream對象作為中間對象艘策,最后再調(diào)用這個生成的Stream對象來完成最終的操作,最后一步的操作只能進行一次渊季,之后朋蔫,此流已經(jīng)沒了(生命周期已結(jié)束)。

Example:

Stream<String> stream =
    Stream.of("d2", "a2", "b1", "b3", "c")
        .filter(s -> s.startsWith("a"));

stream.anyMatch(s -> true);  // The Stream has been used and is now consumed.
stream.noneMatch(s -> true); // IllegalStateException; stream was already used

Closing Streams

Stream接口擴展了 AutoCloseable却汉。Streams可以通過調(diào)用 close方法或使用try-with -resource語句來關(guān)閉驯妄。

請注意,Stream通常不必關(guān)閉合砂。僅需要關(guān)閉在IO通道上運行的流青扔。 大多數(shù)Stream 型不對資源操作,因此不需要關(guān)閉。

Stream 應(yīng)該關(guān)閉的示例用例是微猖,當您從文件創(chuàng)建一個Stream 行時:

try(final Stream<String> lines = Files.lines(Paths.get("somePath"))){
    lines.forEach(System.out::println);
}

Stream接口也聲明了Stream.onClose() 方法谈息,它允許你注冊 Runnable處理程序,當 流關(guān)閉励两。 一個示例用例是產(chǎn)生流的代碼需要知道它何時被消耗以執(zhí)行一些清理黎茎。

public Stream<String>streamAndDelete(Path path) throws IOException {
    return Files.lines(path)
        .onClose(()->someClass.deletePath(path));
}

運行處理程序只有在調(diào)用close() 方法時才會執(zhí)行,例如通過try-with-resources:

Path myPath = Paths.get("somePath");

try(final Stream<String> lines = streamAndDelete(myPath)){
    lines.forEach(System.out::println);
}
Files.exists(myPath); // returns false

If close() isn't called, explicitly or implicitly, then the handler will not be called either:
如果沒有明確或隱式地調(diào)用close()当悔,那么處理程序不會被調(diào)用:

streamAndDelete(myPath)
    .forEach(System.out::println);
Files.exists(myPath); // returns true 

Processing Order

Stream對象的處理可以是順序或 parallel(并行)傅瞻。

在** sequential **模式中,按照“Stream”的源的順序處理元素盲憎。 如果Stream是有序的(例如 SortedMap實現(xiàn)或List嗅骄,處理過程保證匹配源的排序。 然而饼疙,在其他情況下溺森,應(yīng)注意不要依賴于順序(參見:是Java的HashMap`` keySet()迭代順序一致?)窑眯。

Example:

List<Integer> integerList = Arrays.asList(0, 1, 2, 3, 42); 

// sequential 
long howManyOddNumbers = integerList.stream()
                                    .filter(e -> (e % 2) == 1).count(); 

System.out.println(howManyOddNumbers); // Output: 2

Live on Ideone

并行模式允許在多個核上使用多個線程屏积,但不能保證處理元素的順序。

如果在順序的 Stream 上雖然調(diào)用了多個方法磅甩,則不一定必須要調(diào)用每個方法炊林。 例如,如果一個 Stream 被過濾卷要,并且元素的數(shù)量減少到一渣聚,則不會發(fā)生對諸如sort的方法的后續(xù)調(diào)用。 這可以提高順序的Stream的性能 - 這是一個并行的Stream不可能實現(xiàn)的優(yōu)化僧叉。

Example:

// parallel
long howManyOddNumbersParallel = integerList.parallelStream()
                                            .filter(e -> (e % 2) == 1).count();
System.out.println(howManyOddNumbersParallel); // Output: 2

Live on Ideone


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奕枝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瓶堕,更是在濱河造成了極大的恐慌隘道,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郎笆,死亡現(xiàn)場離奇詭異谭梗,居然都是意外死亡,警方通過查閱死者的電腦和手機题画,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門默辨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來德频,“玉大人苍息,你說我怎么就攤上這事。” “怎么了竞思?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵表谊,是天一觀的道長。 經(jīng)常有香客問我盖喷,道長爆办,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任课梳,我火速辦了婚禮距辆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘暮刃。我一直安慰自己跨算,他們只是感情好,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布椭懊。 她就那樣靜靜地躺著诸蚕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氧猬。 梳的紋絲不亂的頭發(fā)上背犯,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機與錄音盅抚,去河邊找鬼漠魏。 笑死,一個胖子當著我的面吹牛泉哈,可吹牛的內(nèi)容都是我干的蛉幸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼丛晦,長吁一口氣:“原來是場噩夢啊……” “哼奕纫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烫沙,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤匹层,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锌蓄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體升筏,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年瘸爽,在試婚紗的時候發(fā)現(xiàn)自己被綠了您访。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡剪决,死狀恐怖灵汪,靈堂內(nèi)的尸體忽然破棺而出檀训,到底是詐尸還是另有隱情,我是刑警寧澤享言,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布峻凫,位于F島的核電站,受9級特大地震影響览露,放射性物質(zhì)發(fā)生泄漏荧琼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一差牛、第九天 我趴在偏房一處隱蔽的房頂上張望命锄。 院中可真熱鬧,春花似錦偏化、人聲如沸累舷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽被盈。三九已至,卻和暖如春搭伤,著一層夾襖步出監(jiān)牢的瞬間只怎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工怜俐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留身堡,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓拍鲤,卻偏偏與公主長得像贴谎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子季稳,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理擅这,服務(wù)發(fā)現(xiàn),斷路器景鼠,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • 來源:重走Java基礎(chǔ)之Streams(四)作者:知秋博客:一葉知秋轉(zhuǎn)載請注明來源和作者仲翎! 接上篇重走Java基礎(chǔ)...
    極樂君閱讀 473評論 0 3
  • 來源:重走Java基礎(chǔ)之Streams(二)作者:知秋(極樂科技知乎專欄原創(chuàng)作者)博客:一葉知秋 接上篇重走Jav...
    極樂君閱讀 505評論 0 2
  • 本文采用實例驅(qū)動的方式,對JAVA8的stream API進行一個深入的介紹铛漓。雖然JAVA8中的stream AP...
    浮梁翁閱讀 25,723評論 3 50
  • 第一章 為什么要關(guān)心Java 8 使用Stream庫來選擇最佳低級執(zhí)行機制可以避免使用Synchronized(同...
    謝隨安閱讀 1,486評論 0 4