Java8 Stream語法詳解

1. Stream初體驗(yàn)

我們先來看看Java里面是怎么定義Stream的:

A sequence of elements supporting sequential and parallel aggregate operations.

我們來解讀一下上面的那句話:

Stream是元素的集合范舀,這點(diǎn)讓Stream看起來用些類似Iterator癞谒;

可以支持順序和并行的對(duì)原Stream進(jìn)行匯聚的操作;

大家可以把Stream當(dāng)成一個(gè)高級(jí)版本的Iterator。原始版本的Iterator蛾茉,用戶只能一個(gè)一個(gè)的遍歷元素并對(duì)其執(zhí)行某些操作;高級(jí)版本的Stream伏穆,用戶只要給出需要對(duì)其包含的元素執(zhí)行什么操作窥妇,比如“過濾掉長(zhǎng)度大于10的字符串”、“獲取每個(gè)字符串的首字母”等怪蔑,具體這些操作如何應(yīng)用到每個(gè)元素上里覆,就給Stream就好了!(這個(gè)秘籍缆瓣,一般人我不告訴他:))大家看完這些可能對(duì)Stream還沒有一個(gè)直觀的認(rèn)識(shí)喧枷,莫急,咱們來段代碼弓坞。

//Lists是Guava中的一個(gè)工具類

List nums = Lists.newArrayList(1,null,3,4,null,6);

nums.stream().filter(num -> num != null).count();

上面這段代碼是獲取一個(gè)List中隧甚,元素不為null的個(gè)數(shù)。這段代碼雖然很簡(jiǎn)短渡冻,但是卻是一個(gè)很好的入門級(jí)別的例子來體現(xiàn)如何使用Stream戚扳,正所謂“麻雀雖小五臟俱全”。我們現(xiàn)在開始深入解刨這個(gè)例子族吻,完成以后你可能可以基本掌握Stream的用法帽借!

1.1 剖析Stream通用語法

圖片就是對(duì)于Stream例子的一個(gè)解析,可以很清楚的看見:原本一條語句被三種顏色的框分割成了三個(gè)部分超歌。紅色框中的語句是一個(gè)Stream的生命開始的地方砍艾,負(fù)責(zé)創(chuàng)建一個(gè)Stream實(shí)例;綠色框中的語句是賦予Stream靈魂的地方巍举,把一個(gè)Stream轉(zhuǎn)換成另外一個(gè)Stream脆荷,紅框的語句生成的是一個(gè)包含所有nums變量的Stream,進(jìn)過綠框的filter方法以后,重新生成了一個(gè)過濾掉原nums列表所有null以后的Stream蜓谋;藍(lán)色框中的語句是豐收的地方梦皮,把Stream的里面包含的內(nèi)容按照某種算法來匯聚成一個(gè)值,例子中是獲取Stream中包含的元素個(gè)數(shù)孤澎。如果這樣解析以后届氢,還不理解,那就只能動(dòng)用“核武器”–圖形化覆旭,一圖抵千言退子!

在此我們總結(jié)一下使用Stream的基本步驟:

創(chuàng)建Stream;

轉(zhuǎn)換Stream型将,每次轉(zhuǎn)換原有Stream對(duì)象不改變寂祥,返回一個(gè)新的Stream對(duì)象(**可以有多次轉(zhuǎn)換**);

對(duì)Stream進(jìn)行聚合(Reduce)操作七兜,獲取想要的結(jié)果丸凭;

2. 創(chuàng)建Stream

最常用的創(chuàng)建Stream有兩種途徑:

通過Stream接口的靜態(tài)工廠方法(注意:Java8里接口可以帶靜態(tài)方法);

通過Collection接口的默認(rèn)方法(默認(rèn)方法:Default method腕铸,也是Java8中的一個(gè)新特性惜犀,就是接口中的一個(gè)帶有實(shí)現(xiàn)的方法,后續(xù)文章會(huì)有介紹)–stream()狠裹,把一個(gè)Collection對(duì)象轉(zhuǎn)換成Stream

2.1 使用Stream靜態(tài)方法來創(chuàng)建Stream

1. of方法:有兩個(gè)overload方法虽界,一個(gè)接受變長(zhǎng)參數(shù),一個(gè)接口單一值

Stream integerStream = Stream.of(1, 2, 3, 5);

Stream stringStream = Stream.of("taobao");

2. generator方法:生成一個(gè)無限長(zhǎng)度的Stream涛菠,其元素的生成是通過給定的Supplier(這個(gè)接口可以看成一個(gè)對(duì)象的工廠莉御,每次調(diào)用返回一個(gè)給定類型的對(duì)象)

? ? Stream.generate(new Supplier() {

? ? ? ? ? @Override

? ? ? ? ? public Double get() {

????????????????return Math.random();

? ? ? ? ? ?}

? ? ? ? });

Stream.generate(() -> Math.random());

? ? Stream.generate(Math::random);


三條語句的作用都是一樣的,只是使用了lambda表達(dá)式和方法引用的語法來簡(jiǎn)化代碼俗冻。每條語句其實(shí)都是生成一個(gè)無限長(zhǎng)度的Stream礁叔,其中值是隨機(jī)的。這個(gè)無限長(zhǎng)度Stream是懶加載迄薄,一般這種無限長(zhǎng)度的Stream都會(huì)配合Stream的limit()方法來用琅关。

3. iterate方法:也是生成無限長(zhǎng)度的Stream,和generator不同的是噪奄,其元素的生成是重復(fù)對(duì)給定的種子值(seed)調(diào)用用戶指定函數(shù)來生成的死姚。其中包含的元素可以認(rèn)為是:seed,f(seed),f(f(seed))無限循環(huán)

? ? Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);


這段代碼就是先獲取一個(gè)無限長(zhǎng)度的正整數(shù)集合的Stream勤篮,然后取出前10個(gè)打印。千萬記住使用limit方法色罚,不然會(huì)無限打印下去碰缔。

2.2 通過Collection子類獲取Stream

這個(gè)在本文的第一個(gè)例子中就展示了從List對(duì)象獲取其對(duì)應(yīng)的Stream對(duì)象,如果查看Java doc就可以發(fā)現(xiàn)Collection接口有一個(gè)stream方法戳护,所以其所有子類都都可以獲取對(duì)應(yīng)的Stream對(duì)象金抡。

public interface Collection extends Iterable {

? ? //其他方法省略

default Stream stream() {

? ? ? ? return StreamSupport.stream(spliterator(), false);

? ? }

}

3. 轉(zhuǎn)換Stream

轉(zhuǎn)換Stream其實(shí)就是把一個(gè)Stream通過某些行為轉(zhuǎn)換成一個(gè)新的Stream瀑焦。Stream接口中定義了幾個(gè)常用的轉(zhuǎn)換方法,下面我們挑選幾個(gè)常用的轉(zhuǎn)換方法來解釋梗肝。

1. distinct: 對(duì)于Stream中包含的元素進(jìn)行去重操作(去重邏輯依賴元素的equals方法)榛瓮,新生成的Stream中沒有重復(fù)的元素;

distinct方法示意圖(**以下所有的示意圖都要感謝[RxJava](https://github.com/Netflix/RxJava)項(xiàng)目的doc中的圖片給予的靈感, 如果示意圖表達(dá)的有錯(cuò)誤和不準(zhǔn)確的地方巫击,請(qǐng)直接聯(lián)系我禀晓。**):

2. filter: 對(duì)于Stream中包含的元素使用給定的過濾函數(shù)進(jìn)行過濾操作,新生成的Stream只包含符合條件的元素坝锰;

filter方法示意圖:

3. map: 對(duì)于Stream中包含的元素使用給定的轉(zhuǎn)換函數(shù)進(jìn)行轉(zhuǎn)換操作粹懒,新生成的Stream只包含轉(zhuǎn)換生成的元素。這個(gè)方法有三個(gè)對(duì)于原始類型的變種方法顷级,分別是:mapToInt凫乖,mapToLong和mapToDouble。這三個(gè)方法也比較好理解弓颈,比如mapToInt就是把原始Stream轉(zhuǎn)換成一個(gè)新的Stream帽芽,這個(gè)新生成的Stream中的元素都是int類型。之所以會(huì)有這樣三個(gè)變種方法翔冀,可以免除自動(dòng)裝箱/拆箱的額外消耗导街;

map方法示意圖:

4. flatMap:和map類似,不同的是其每個(gè)元素轉(zhuǎn)換得到的是Stream對(duì)象橘蜜,會(huì)把子Stream中的元素壓縮到父集合中菊匿;

flatMap方法示意圖:

5. peek: 生成一個(gè)包含原Stream的所有元素的新Stream,同時(shí)會(huì)提供一個(gè)消費(fèi)函數(shù)(Consumer實(shí)例)计福,新Stream每個(gè)元素被消費(fèi)的時(shí)候都會(huì)執(zhí)行給定的消費(fèi)函數(shù)跌捆;

peek方法示意圖:

6. limit: 對(duì)一個(gè)Stream進(jìn)行截?cái)嗖僮鳎@取其前N個(gè)元素象颖,如果原Stream中包含的元素個(gè)數(shù)小于N佩厚,那就獲取其所有的元素;

limit方法示意圖:

7. skip: 返回一個(gè)丟棄原Stream的前N個(gè)元素后剩下元素組成的新Stream说订,如果原Stream中包含的元素個(gè)數(shù)小于N抄瓦,那么返回空Stream;

skip方法示意圖:

8. 在一起,在一起陶冷!

? ? List nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);

System.out.println(“sum is:”+nums.stream().filter(num -> num != null).

? ? distinct().mapToInt(num -> num * 2).

? ? ? ? ? ? ? ? peek(System.out::println).skip(2).limit(4).sum());


這段代碼演示了上面介紹的所有轉(zhuǎn)換方法(除了flatMap)钙姊,簡(jiǎn)單解釋一下這段代碼的含義:給定一個(gè)Integer類型的List,獲取其對(duì)應(yīng)的Stream對(duì)象埂伦,然后進(jìn)行過濾掉null煞额,再去重,再每個(gè)元素乘以2,再每個(gè)元素被消費(fèi)的時(shí)候打印自身膊毁,在跳過前兩個(gè)元素胀莹,最后去前四個(gè)元素進(jìn)行加和運(yùn)算(解釋一大堆,很像廢話婚温,因?yàn)榛究戳朔椒椭酪鍪裁戳嗣柩妗_@個(gè)就是聲明式編程的一大好處!)栅螟。大家可以參考上面對(duì)于每個(gè)方法的解釋荆秦,看看最終的輸出是什么。

9. 性能問題

有些細(xì)心的同學(xué)可能會(huì)有這樣的疑問:在對(duì)于一個(gè)Stream進(jìn)行多次轉(zhuǎn)換操作嵌巷,每次都對(duì)Stream的每個(gè)元素進(jìn)行轉(zhuǎn)換萄凤,而且是執(zhí)行多次,這樣時(shí)間復(fù)雜度就是一個(gè)for循環(huán)里把所有操作都做掉的N(轉(zhuǎn)換的次數(shù))倍啊搪哪。其實(shí)不是這樣的靡努,轉(zhuǎn)換操作都是lazy的,多個(gè)轉(zhuǎn)換操作只會(huì)在匯聚操作(見下節(jié))的時(shí)候融合起來晓折,一次循環(huán)完成惑朦。我們可以這樣簡(jiǎn)單的理解,Stream里有個(gè)操作函數(shù)的集合漓概,每次轉(zhuǎn)換操作就是把轉(zhuǎn)換函數(shù)放入這個(gè)集合中漾月,在匯聚操作的時(shí)候循環(huán)Stream對(duì)應(yīng)的集合,然后對(duì)每個(gè)元素執(zhí)行所有的函數(shù)胃珍。

4. 匯聚(Reduce)Stream

匯聚這個(gè)詞梁肿,是我自己翻譯的,如果大家有更好的翻譯觅彰,可以在下面留言吩蔑。在官方文檔中是reduce,也叫fold填抬。

在介紹匯聚操作之前烛芬,我們先看一下Java doc中對(duì)于其定義:

A reduction operation (also called a fold) takes a sequence of input elements and combines them into a single summary result by repeated application of a combining operation, such as finding the sum or maximum of a set of numbers, or accumulating elements into a list. The streams classes have multiple forms of general reduction operations, called reduce() and collect(), as well as multiple specialized reduction forms such as sum(), max(), or count().

簡(jiǎn)單翻譯一下:匯聚操作(也稱為折疊)接受一個(gè)元素序列為輸入,反復(fù)使用某個(gè)合并操作飒责,把序列中的元素合并成一個(gè)匯總的結(jié)果赘娄。比如查找一個(gè)數(shù)字列表的總和或者最大值,或者把這些數(shù)字累積成一個(gè)List對(duì)象宏蛉。Stream接口有一些通用的匯聚操作遣臼,比如reduce()和collect();也有一些特定用途的匯聚操作拾并,比如sum(),max()和count()暑诸。注意:sum方法不是所有的Stream對(duì)象都有的蚌讼,只有IntStream辟灰、LongStream和DoubleStream是實(shí)例才有个榕。

下面會(huì)分兩部分來介紹匯聚操作:

可變匯聚:把輸入的元素們累積到一個(gè)可變的容器中,比如Collection或者StringBuilder芥喇;

其他匯聚:除去可變匯聚剩下的西采,一般都不是通過反復(fù)修改某個(gè)可變對(duì)象,而是通過把前一次的匯聚結(jié)果當(dāng)成下一次的入?yún)⒓炭兀磸?fù)如此械馆。比如reduce,count武通,allMatch霹崎;

4.1 可變匯聚

可變匯聚對(duì)應(yīng)的只有一個(gè)方法:collect,正如其名字顯示的冶忱,它可以把Stream中的要有元素收集到一個(gè)結(jié)果容器中(比如Collection)尾菇。先看一下最通用的collect方法的定義(還有其他override方法):

R collect(Supplier supplier,

? ? ? ? ? ? ? ? ? BiConsumer accumulator,

? ? ? ? ? ? ? ? ? BiConsumer combiner);

先來看看這三個(gè)參數(shù)的含義:Supplier supplier是一個(gè)工廠函數(shù),用來生成一個(gè)新的容器囚枪;BiConsumer accumulator也是一個(gè)函數(shù)派诬,用來把Stream中的元素添加到結(jié)果容器中;BiConsumer combiner還是一個(gè)函數(shù)链沼,用來把中間狀態(tài)的多個(gè)結(jié)果容器合并成為一個(gè)(并發(fā)的時(shí)候會(huì)用到)默赂。看暈了括勺?來段代碼缆八!

List nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);

? ? ? ? List numsWithoutNull = nums.stream().filter(num -> num != null).

? ? ? ? ? ? ? ? collect(() -> new ArrayList(),

? ? ? ? ? ? ? ? ? ? ? ? (list, item) -> list.add(item),

? ? ? ? ? ? ? ? ? ? ? ? (list1, list2) -> list1.addAll(list2));

上面這段代碼就是對(duì)一個(gè)元素是Integer類型的List,先過濾掉全部的null疾捍,然后把剩下的元素收集到一個(gè)新的List中奈辰。進(jìn)一步看一下collect方法的三個(gè)參數(shù),都是lambda形式的函數(shù)(*上面的代碼可以使用方法引用來簡(jiǎn)化拾氓,留給讀者自己去思考*)冯挎。

第一個(gè)函數(shù)生成一個(gè)新的ArrayList實(shí)例;

第二個(gè)函數(shù)接受兩個(gè)參數(shù)咙鞍,第一個(gè)是前面生成的ArrayList對(duì)象房官,二個(gè)是stream中包含的元素,函數(shù)體就是把stream中的元素加入ArrayList對(duì)象中续滋。第二個(gè)函數(shù)被反復(fù)調(diào)用直到原stream的元素被消費(fèi)完畢翰守;

第三個(gè)函數(shù)也是接受兩個(gè)參數(shù),這兩個(gè)都是ArrayList類型的疲酌,函數(shù)體就是把第二個(gè)ArrayList全部加入到第一個(gè)中蜡峰;

但是上面的collect方法調(diào)用也有點(diǎn)太復(fù)雜了了袁,沒關(guān)系!我們來看一下collect方法另外一個(gè)override的版本湿颅,其依賴[Collector](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html)载绿。

R collect(Collector collector);

這樣清爽多了!少年油航,還有好消息崭庸,Java8還給我們提供了Collector的工具類–[Collectors](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html),其中已經(jīng)定義了一些靜態(tài)工廠方法谊囚,比如:Collectors.toCollection()收集到Collection中, Collectors.toList()收集到List中和Collectors.toSet()收集到Set中怕享。這樣的靜態(tài)方法還有很多,這里就不一一介紹了镰踏,大家可以直接去看JavaDoc函筋。下面看看使用Collectors對(duì)于代碼的簡(jiǎn)化:

List numsWithoutNull = nums.stream().filter(num -> num != null).

? ? ? ? ? ? ? ? collect(Collectors.toList());

4.2 其他匯聚

– reduce方法:reduce方法非常的通用,后面介紹的count奠伪,sum等都可以使用其實(shí)現(xiàn)跌帐。reduce方法有三個(gè)override的方法,本文介紹兩個(gè)最常用的芳来,最后一個(gè)留給讀者自己學(xué)習(xí)含末。先來看reduce方法的第一種形式,其方法定義如下:

? ? Optional reduce(BinaryOperator accumulator);


接受一個(gè)BinaryOperator類型的參數(shù)即舌,在使用的時(shí)候我們可以用lambda表達(dá)式來佣盒。

? ? List ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);

? ? System.out.println("ints sum is:" + ints.stream().reduce((sum, item) -> sum + item).get());


可以看到reduce方法接受一個(gè)函數(shù),這個(gè)函數(shù)有兩個(gè)參數(shù)顽聂,第一個(gè)參數(shù)是上次函數(shù)執(zhí)行的返回值(也稱為中間結(jié)果)肥惭,第二個(gè)參數(shù)是stream中的元素,這個(gè)函數(shù)把這兩個(gè)值相加紊搪,得到的和會(huì)被賦值給下次執(zhí)行這個(gè)函數(shù)的第一個(gè)參數(shù)蜜葱。要注意的是:**第一次執(zhí)行的時(shí)候第一個(gè)參數(shù)的值是Stream的第一個(gè)元素,第二個(gè)參數(shù)是Stream的第二個(gè)元素**耀石。這個(gè)方法返回值類型是Optional牵囤,這是Java8防止出現(xiàn)NPE的一種可行方法,后面的文章會(huì)詳細(xì)介紹滞伟,這里就簡(jiǎn)單的認(rèn)為是一個(gè)容器揭鳞,其中可能會(huì)包含0個(gè)或者1個(gè)對(duì)象。

這個(gè)過程可視化的結(jié)果如圖:

reduce方法還有一個(gè)很常用的變種:

? ? T reduce(T identity, BinaryOperator accumulator);


這個(gè)定義上上面已經(jīng)介紹過的基本一致梆奈,不同的是:它允許用戶提供一個(gè)循環(huán)計(jì)算的初始值野崇,如果Stream為空,就直接返回該值亩钟。而且這個(gè)方法不會(huì)返回Optional乓梨,因?yàn)槠洳粫?huì)出現(xiàn)null值鳖轰。下面直接給出例子,就不再做說明了扶镀。

? ? List ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);

? ? System.out.println("ints sum is:" + ints.stream().reduce(0, (sum, item) -> sum + item));


– count方法:獲取Stream中元素的個(gè)數(shù)蕴侣。比較簡(jiǎn)單,這里就直接給出例子狈惫,不做解釋了睛蛛。

? ? List ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);

? ? System.out.println("ints sum is:" + ints.stream().count());

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胧谈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荸频,老刑警劉巖菱肖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異旭从,居然都是意外死亡稳强,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門和悦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來退疫,“玉大人,你說我怎么就攤上這事鸽素“保” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵馍忽,是天一觀的道長(zhǎng)棒坏。 經(jīng)常有香客問我,道長(zhǎng)遭笋,這世上最難降的妖魔是什么坝冕? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瓦呼,結(jié)果婚禮上喂窟,老公的妹妹穿的比我還像新娘。我一直安慰自己央串,他們只是感情好磨澡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蹋辅,像睡著了一般钱贯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侦另,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天秩命,我揣著相機(jī)與錄音尉共,去河邊找鬼。 笑死弃锐,一個(gè)胖子當(dāng)著我的面吹牛袄友,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霹菊,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼剧蚣,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了旋廷?” 一聲冷哼從身側(cè)響起鸠按,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饶碘,沒想到半個(gè)月后目尖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扎运,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年瑟曲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豪治。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洞拨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出负拟,到底是詐尸還是另有隱情烦衣,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布齿椅,位于F島的核電站琉挖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏涣脚。R本人自食惡果不足惜示辈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遣蚀。 院中可真熱鬧矾麻,春花似錦、人聲如沸芭梯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玖喘。三九已至甩牺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間累奈,已是汗流浹背贬派。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工急但, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搞乏。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓波桩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親请敦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子镐躲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • 本文將會(huì)詳細(xì)講解Stream的使用方法(不會(huì)涉及Stream的原理,因?yàn)檫@個(gè)系列的文章還是一個(gè)快速學(xué)習(xí)如何使用的)...
    光劍書架上的書閱讀 5,553評(píng)論 0 16
  • Int Double Long 設(shè)置特定的stream類型侍筛, 提高性能萤皂,增加特定的函數(shù) 無存儲(chǔ)。stream不是一...
    patrick002閱讀 1,267評(píng)論 0 0
  • 前言: 講Stream之前勾笆,先來用個(gè)小需求帶入本文敌蚜。畢竟代碼看的最清楚。 正文: 項(xiàng)目某個(gè)頁面有個(gè)需求窝爪,將關(guān)鍵詞和...
    T9的第三個(gè)三角閱讀 2,397評(píng)論 1 9
  • 了解Stream ? Java8中有兩個(gè)最為重要的改變,一個(gè)是Lambda表達(dá)式齐媒,另一個(gè)就是Stream AP...
    龍歷旗閱讀 3,304評(píng)論 3 4
  • 本文采用實(shí)例驅(qū)動(dòng)的方式蒲每,對(duì)JAVA8的stream API進(jìn)行一個(gè)深入的介紹。雖然JAVA8中的stream AP...
    浮梁翁閱讀 25,723評(píng)論 3 50