偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

新聞 前端
我們都知道 Lambda 和 Stream 是 Java 8 的兩大亮點功能,在前面的文章里已經(jīng)介紹過 Lambda 相關(guān)知識,這次介紹下 Java 8 的 Stream 流操作。

我們都知道 Lambda 和 Stream 是 Java 8 的兩大亮點功能,在前面的文章里已經(jīng)介紹過 Lambda 相關(guān)知識,這次介紹下 Java 8 的 Stream 流操作。它完全不同于 java.io 包的 Input/Output Stream ,也不是大數(shù)據(jù)實時處理的 Stream 流。這個 Stream 流操作是 Java 8 對集合操作功能的增強(qiáng),專注于對集合的各種高效、便利、優(yōu)雅的聚合操作。借助于 Lambda 表達(dá)式,顯著的提高編程效率可讀性。且 Stream 提供了并行計算模式,可以簡潔的編寫出并行代碼,能充分發(fā)揮如今計算機(jī)的多核處理優(yōu)勢。

1. Stream 流介紹

Stream 不同于其他集合框架,它也不是某種數(shù)據(jù)結(jié)構(gòu),也不會保存數(shù)據(jù),但是它負(fù)責(zé)相關(guān)計算,使用起來更像一個高級的迭代器。在之前的迭代器中,我們只能先遍歷然后在執(zhí)行業(yè)務(wù)操作,而現(xiàn)在只需要指定執(zhí)行什么操作, Stream 就會隱式的遍歷然后做出想要的操作。另外 Stream 和迭代器一樣的只能單向處理,如同奔騰長江之水一去而不復(fù)返。

由于 Stream 流提供了惰性計算并行處理的能力,在使用并行計算方式時數(shù)據(jù)會被自動分解成多段然后并行處理,最后將結(jié)果匯總。所以 Stream 操作可以讓程序運(yùn)行變得更加高效。

2. Stream 流概念

Stream 流的使用總是按照一定的步驟進(jìn)行,可以抽象出下面的使用流程。

數(shù)據(jù)源(source) -> 數(shù)據(jù)處理/轉(zhuǎn)換(intermedia) -> 結(jié)果處理(terminal )

2.1. 數(shù)據(jù)源

數(shù)據(jù)源(source)也就是數(shù)據(jù)的來源,可以通過多種方式獲得 Stream 數(shù)據(jù)源,下面列舉幾種常見的獲取方式。

 

  • Collection.stream(); 從集合獲取流。
  • Collection.parallelStream(); 從集合獲取并行流。
  • Arrays.stream(T array) or Stream.of(); 從數(shù)組獲取流。
  • BufferedReader.lines(); 從輸入流中獲取流。
  • IntStream.of() ; 從靜態(tài)方法中獲取流。
  • Stream.generate(); 自己生成流

 

2.2. 數(shù)據(jù)處理

數(shù)據(jù)處理/轉(zhuǎn)換(intermedia)步驟可以有多個操作,這步也被稱為intermedia(中間操作)。在這個步驟中不管怎樣操作,它返回的都是一個新的流對象,原始數(shù)據(jù)不會發(fā)生任何改變,而且這個步驟是惰性計算處理的,也就是說只調(diào)用方法并不會開始處理,只有在真正的開始收集結(jié)果時,中間操作才會生效,而且如果遍歷沒有完成,想要的結(jié)果已經(jīng)獲取到了(比如獲取第一個值),會停止遍歷,然后返回結(jié)果。惰性計算可以顯著提高運(yùn)行效率。

數(shù)據(jù)處理演示。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

數(shù)據(jù)處理/轉(zhuǎn)換操作自然不止是上面演示的過濾 filter 和 map映射兩種,另外還有 map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered 等。

2.3. 收集結(jié)果

結(jié)果處理(terminal )是流處理的最后一步,執(zhí)行完這一步之后流會被徹底用盡,流也不能繼續(xù)操作了。也只有到了這個操作的時候,流的數(shù)據(jù)處理/轉(zhuǎn)換等中間過程才會開始計算,也就是上面所說的惰性計算。結(jié)果處理也必定是流操作的最后一步。

常見的結(jié)果處理操作有 forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator 等。

下面演示了簡單的結(jié)果處理的例子。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

2.4. short-circuiting

有一種 Stream 操作被稱作 short-circuiting ,它是指當(dāng) Stream 流無限大但是需要返回的 Stream 流是有限的時候,而又希望它能在有限的時間內(nèi)計算出結(jié)果,那么這個操作就被稱為short-circuiting。例如 findFirst 操作。

3. Stream 流使用

Stream 流在使用時候總是借助于 Lambda 表達(dá)式進(jìn)行操作,Stream 流的操作也有很多種方式,下面列舉的是常用的 11 種操作。

3.1. Stream 流獲取

獲取 Stream 的幾種方式在上面的 Stream 數(shù)據(jù)源里已經(jīng)介紹過了,下面是針對上面介紹的幾種獲取 Stream 流的使用示例。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.2. forEach

forEach 是 Strean 流中的一個重要方法,用于遍歷 Stream 流,它支持傳入一個標(biāo)準(zhǔn)的 Lambda 表達(dá)式。但是它的遍歷不能通過 return/break 進(jìn)行終止。同時它也是一個 terminal 操作,執(zhí)行之后 Stream 流中的數(shù)據(jù)會被消費(fèi)掉。

如輸出對象。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.3. map / flatMap

使用 map 把對象一對一映射成另一種對象或者形式。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

上面的 map 可以把數(shù)據(jù)進(jìn)行一對一的映射,而有些時候關(guān)系可能不止 1對 1那么簡單,可能會有1對多。這時可以使用 flatMap。下面演示使用 flatMap把對象扁平化展開。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.4. filter

使用 filter 進(jìn)行數(shù)據(jù)篩選,挑選出想要的元素,下面的例子演示怎么挑選出偶數(shù)數(shù)字。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

得到如下結(jié)果。

2,4,6,8,

3.5. findFirst

findFirst 可以查找出 Stream 流中的第一個元素,它返回的是一個 Optional 類型,如果還不知道 Optional 類的用處,可以參考之前文章 Jdk14都要出了,還不能使用 Optional優(yōu)雅的處理空指針? 。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

findFirst 方法在查找到需要的數(shù)據(jù)之后就會返回不再遍歷數(shù)據(jù)了,也因此 findFirst 方法可以對有無限數(shù)據(jù)的 Stream 流進(jìn)行操作,也可以說 findFirst 是一個 short-circuiting 操作。

3.6. collect / toArray

Stream 流可以輕松的轉(zhuǎn)換為其他結(jié)構(gòu),下面是幾種常見的示例。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.7. limit / skip

獲取或者扔掉前 n 個元素

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.8. Statistics

數(shù)學(xué)統(tǒng)計功能,求一組數(shù)組的最大值、最小值、個數(shù)、數(shù)據(jù)和、平均數(shù)等。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.9. groupingBy

分組聚合功能,和數(shù)據(jù)庫的 Group by 的功能一致。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.10. partitioningBy

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

3.11. 進(jìn)階 - 自己生成 Stream 流

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

上面的例子中 Stream 流是無限的,但是獲取到的結(jié)果是有限的,使用了 Limit 限制獲取的數(shù)量,所以這個操作也是 short-circuiting 操作。

4. Stream 流優(yōu)點

4.1. 簡潔優(yōu)雅

正確使用并且正確格式化的 Stream 流操作代碼不僅簡潔優(yōu)雅,更讓人賞心悅目。下面對比下在使用 Stream 流和不使用 Stream 流時相同操作的編碼風(fēng)格。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

如果是使用 Stream 流操作。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

4.2. 惰性計算

上面有提到,數(shù)據(jù)處理/轉(zhuǎn)換(intermedia) 操作 map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered 等這些操作,在調(diào)用方法時并不會立即調(diào)用,而是在真正使用的時候才會生效,這樣可以讓操作延遲到真正需要使用的時刻。

下面會舉個例子演示這一點。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

如果沒有 惰性計算,那么很明顯會先輸出偶數(shù),然后輸出 分割線。而實際的效果是。

分割線

2

4

6

可見 惰性計算 把計算延遲到了真正需要的時候。

4.3. 并行計算

獲取 Stream 流時可以使用 parallelStream 方法代替 stream 方法以獲取并行處理流,并行處理可以充分的發(fā)揮多核優(yōu)勢,而且不增加編碼的復(fù)雜性。

下面的代碼演示了生成一千萬個隨機(jī)數(shù)后,把每個隨機(jī)數(shù)乘以2然后求和時,串行計算和并行計算的耗時差異。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

得到如下輸出。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

效果顯而易見,代碼簡潔優(yōu)雅。

5. Stream 流建議

5.1 保證正確排版

從上面的使用案例中,可以發(fā)現(xiàn)使用 Stream 流操作的代碼非常簡潔,而且可讀性更高。但是如果不正確的排版,那么看起來將會很糟糕,比如下面的同樣功能的代碼例子,多幾層操作呢,是不是有些讓人頭大?

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

5.1 保證函數(shù)純度

如果想要你的 Stream 流對于每次的相同操作的結(jié)果都是相同的話,那么你必須保證 Lambda 表達(dá)式的純度,也就是下面亮點。

  • Lambda 中不會更改任何元素。
  • Lambda 中不依賴于任何可能更改的元素。

這兩點對于保證函數(shù)的冪等非常重要,不然你程序執(zhí)行結(jié)果可能會變得難以預(yù)測,就像下面的例子。

還看不懂同事的代碼?超強(qiáng)的 Stream 流操作姿勢還不學(xué)習(xí)一下

 

責(zé)任編輯:張燕妮 來源: 今日頭條
相關(guān)推薦

2022-06-16 14:07:26

Java代碼代碼review

2022-07-26 14:38:08

JavaScriptWeb安全自動化

2020-03-30 16:45:06

代碼看不懂

2021-08-30 07:49:34

數(shù)據(jù)庫數(shù)倉Doris

2022-02-07 09:05:00

GitHub功能AI

2021-12-09 11:59:49

JavaScript前端提案

2019-12-09 08:29:26

Netty架構(gòu)系統(tǒng)

2020-09-04 15:13:43

Java 8接口物流信息

2013-07-08 10:49:03

程序員代碼看懂代碼

2020-03-06 11:30:08

JavaGitHub編程

2021-02-23 10:36:09

Linux命令kmdr

2019-10-24 08:56:38

語言代碼Java

2022-12-12 07:40:36

服務(wù)器項目Serverless

2024-12-26 16:47:48

2023-11-23 17:02:34

LinuxSED工具

2023-06-30 08:01:04

Reactuse關(guān)鍵詞

2024-12-09 08:00:00

C++代碼

2014-03-12 09:25:33

產(chǎn)品經(jīng)理Startup

2017-09-19 15:45:39

2020-04-09 10:25:37

Redis分布式算法
點贊
收藏

51CTO技術(shù)棧公眾號