Java8 Stream 語法詳解 & 用法實(shí)例

本文將會詳細(xì)講解Stream的使用方法(不會涉及Stream的原理逸邦,因?yàn)檫@個(gè)系列的文章還是一個(gè)快速學(xué)習(xí)如何使用的)痕鳍。
1. Stream初體驗(yàn)
我們先來看看Java里面是怎么定義Stream的:

A sequence of elements supporting sequential and parallel aggregate operations.

我們來解讀一下上面的那句話:
Stream是元素的集合纷捞,這點(diǎn)讓Stream看起來用些類似Iterator橙弱;
可以支持順序和并行的對原Stream進(jìn)行匯聚的操作顿膨;

大家可以把Stream當(dāng)成一個(gè)高級版本的Iterator萤皂。原始版本的Iterator,用戶只能一個(gè)一個(gè)的遍歷元素并對其執(zhí)行某些操作竭鞍;高級版本的Stream板惑,用戶只要給出需要對其包含的元素執(zhí)行什么操作,比如“過濾掉長度大于10的字符串”偎快、“獲取每個(gè)字符串的首字母”等冯乘,具體這些操作如何應(yīng)用到每個(gè)元素上,就給Stream就好了I辜小(這個(gè)秘籍裆馒,一般人我不告訴他:))大家看完這些可能對Stream還沒有一個(gè)直觀的認(rèn)識,莫急丐怯,咱們來段代碼喷好。

//Lists是Guava中的一個(gè)工具類
List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();

上面這段代碼是獲取一個(gè)List中,元素不為null的個(gè)數(shù)读跷。這段代碼雖然很簡短梗搅,但是卻是一個(gè)很好的入門級別的例子來體現(xiàn)如何使用Stream,正所謂“麻雀雖小五臟俱全”效览。我們現(xiàn)在開始深入解刨這個(gè)例子无切,完成以后你可能可以基本掌握Stream的用法!

1.1 剖析Stream通用語法


圖片就是對于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對象不改變名惩,返回一個(gè)新的Stream對象(可以有多次轉(zhuǎn)換)澎胡;
對Stream進(jìn)行聚合(Reduce)操作,獲取想要的結(jié)果娩鹉;

  1. 創(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ù)文章會有介紹)–stream(),把一個(gè)Collection對象轉(zhuǎn)換成Stream

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

  1. of方法:有兩個(gè)overload方法锈嫩,一個(gè)接受變長參數(shù)受楼,一個(gè)接口單一值
Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
Stream<String> stringStream = Stream.of("taobao");
  1. generator方法:生成一個(gè)無限長度的Stream,其元素的生成是通過給定的Supplier(這個(gè)接口可以看成一個(gè)對象的工廠呼寸,每次調(diào)用返回一個(gè)給定類型的對象)
   Stream.generate(new Supplier<Double>() {
    @Override
    public Double get() {
        return Math.random();
    }
});
Stream.generate(() -> Math.random());
   Stream.generate(Math::random);
   

三條語句的作用都是一樣的艳汽,只是使用了lambda表達(dá)式和方法引用的語法來簡化代碼。每條語句其實(shí)都是生成一個(gè)無限長度的Stream对雪,其中值是隨機(jī)的河狐。這個(gè)無限長度Stream是懶加載,一般這種無限長度的Stream都會配合Stream的limit()方法來用慌植。3. iterate方法:也是生成無限長度的Stream甚牲,和generator不同的是,其元素的生成是重復(fù)對給定的種子值(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è)無限長度的正整數(shù)集合的Stream,然后取出前10個(gè)打印交汤。千萬記住使用limit方法雏赦,不然會無限打印下去。

2.2 通過Collection子類獲取Stream

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

public interface Collection<E> extends Iterable<E> {
//其他方法省略

default  Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
  1. 轉(zhuǎn)換Stream

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

  1. distinct: 對于Stream中包含的元素進(jìn)行去重操作(去重邏輯依賴元素的equals方法)圈浇,新生成的Stream中沒有重復(fù)的元素寥掐;
    distinct方法示意圖(以下所有的示意圖都要感謝RxJava項(xiàng)目的doc中的圖片給予的靈感, 如果示意圖表達(dá)的有錯(cuò)誤和不準(zhǔn)確的地方靴寂,請直接聯(lián)系我。):
    2. filter: 對于Stream中包含的元素使用給定的過濾函數(shù)進(jìn)行過濾操作召耘,新生成的Stream只包含符合條件的元素百炬;

filter方法示意圖:

3. map: 對于Stream中包含的元素使用給定的轉(zhuǎn)換函數(shù)進(jìn)行轉(zhuǎn)換操作,新生成的Stream只包含轉(zhuǎn)換生成的元素污它。這個(gè)方法有三個(gè)對于原始類型的變種方法剖踊,分別是:mapToInt,mapToLong和mapToDouble衫贬。這三個(gè)方法也比較好理解德澈,比如mapToInt就是把原始Stream轉(zhuǎn)換成一個(gè)新的Stream,這個(gè)新生成的Stream中的元素都是int類型祥山。之所以會有這樣三個(gè)變種方法圃验,可以免除自動(dòng)裝箱/拆箱的額外消耗;

map方法示意圖:

4. flatMap:和map類似缝呕,不同的是其每個(gè)元素轉(zhuǎn)換得到的是Stream對象澳窑,會把子Stream中的元素壓縮到父集合中;

flatMap方法示意圖:
5. peek: 生成一個(gè)包含原Stream的所有元素的新Stream供常,同時(shí)會提供一個(gè)消費(fèi)函數(shù)(Consumer實(shí)例)摊聋,新Stream每個(gè)元素被消費(fèi)的時(shí)候都會執(zhí)行給定的消費(fèi)函數(shù);
peek方法示意圖:

6. limit: 對一個(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方法示意圖:
  1. 在一起,在一起手销!
List<Integer> 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),簡單解釋一下這段代碼的含義:給定一個(gè)Integer類型的List图张,獲取其對應(yīng)的Stream對象锋拖,然后進(jìn)行過濾掉null,再去重祸轮,再每個(gè)元素乘以2兽埃,再每個(gè)元素被消費(fèi)的時(shí)候打印自身,在跳過前兩個(gè)元素适袜,最后去前四個(gè)元素進(jìn)行加和運(yùn)算(解釋一大堆柄错,很像廢話,因?yàn)榛究戳朔椒椭酪鍪裁戳恕_@個(gè)就是聲明式編程的一大好處鄙陡!)冕房。大家可以參考上面對于每個(gè)方法的解釋躏啰,看看最終的輸出是什么趁矾。

9.性能問題有些細(xì)心的同學(xué)可能會有這樣的疑問:在對于一個(gè)Stream進(jìn)行多次轉(zhuǎn)換操作,每次都對Stream的每個(gè)元素進(jìn)行轉(zhuǎn)換给僵,而且是執(zhí)行多次毫捣,這樣時(shí)間復(fù)雜度就是一個(gè)for循環(huán)里把所有操作都做掉的N(轉(zhuǎn)換的次數(shù))倍啊。其實(shí)不是這樣的帝际,轉(zhuǎn)換操作都是lazy的蔓同,多個(gè)轉(zhuǎn)換操作只會在匯聚操作(見下節(jié))的時(shí)候融合起來,一次循環(huán)完成蹲诀。我們可以這樣簡單的理解斑粱,Stream里有個(gè)操作函數(shù)的集合,每次轉(zhuǎn)換操作就是把轉(zhuǎn)換函數(shù)放入這個(gè)集合中脯爪,在匯聚操作的時(shí)候循環(huán)Stream對應(yīng)的集合则北,然后對每個(gè)元素執(zhí)行所有的函數(shù)。

匯聚(Reduce)Stream

匯聚這個(gè)詞痕慢,是我自己翻譯的尚揣,如果大家有更好的翻譯,可以在下面留言掖举。在官方文檔中是reduce快骗,也叫fold。

在介紹匯聚操作之前塔次,我們先看一下Java doc中對于其定義:

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().

簡單翻譯一下:匯聚操作(也稱為折疊)接受一個(gè)元素序列為輸入方篮,反復(fù)使用某個(gè)合并操作,把序列中的元素合并成一個(gè)匯總的結(jié)果励负。比如查找一個(gè)數(shù)字列表的總和或者最大值藕溅,或者把這些數(shù)字累積成一個(gè)List對象。Stream接口有一些通用的匯聚操作熄守,比如reduce()和collect()蜈垮;也有一些特定用途的匯聚操作,比如sum(),max()和count()裕照。注意:sum方法不是所有的Stream對象都有的攒发,只有IntStream、LongStream和DoubleStream是實(shí)例才有晋南。
下面會分兩部分來介紹匯聚操作:
可變匯聚:把輸入的元素們累積到一個(gè)可變的容器中惠猿,比如Collection或者StringBuilder;
其他匯聚:除去可變匯聚剩下的负间,一般都不是通過反復(fù)修改某個(gè)可變對象偶妖,而是通過把前一次的匯聚結(jié)果當(dāng)成下一次的入?yún)⒔啵磸?fù)如此。比如reduce趾访,count态秧,allMatch;

4.1 可變匯聚

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


<R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> 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í)候會用到)』璧危看暈了猴鲫?來段代碼!

List<Integer> nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
       List<Integer> numsWithoutNull = nums.stream().filter(num -> num != null).
               collect(() -> new ArrayList<Integer>(),
                       (list, item) -> list.add(item),
                       (list1, list2) -> list1.addAll(list2));

上面這段代碼就是對一個(gè)元素是Integer類型的List影涉,先過濾掉全部的null变隔,然后把剩下的元素收集到一個(gè)新的List中。進(jìn)一步看一下collect方法的三個(gè)參數(shù)蟹倾,都是lambda形式的函數(shù)(上面的代碼可以使用方法引用來簡化匣缘,留給讀者自己去思考)。
第一個(gè)函數(shù)生成一個(gè)新的ArrayList實(shí)例鲜棠;
第二個(gè)函數(shù)接受兩個(gè)參數(shù)肌厨,第一個(gè)是前面生成的ArrayList對象,二個(gè)是stream中包含的元素豁陆,函數(shù)體就是把stream中的元素加入ArrayList對象中柑爸。第二個(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雄坪。

<R, A> R collect(Collector<? super T, A, R> collector);

這樣清爽多了厘熟!少年,還有好消息,Java8還給我們提供了Collector的工具類–Collectors绳姨,其中已經(jīng)定義了一些靜態(tài)工廠方法登澜,比如:Collectors.toCollection()收集到Collection中, Collectors.toList()收集到List中和Collectors.toSet()收集到Set中。這樣的靜態(tài)方法還有很多飘庄,這里就不一一介紹了脑蠕,大家可以直接去看JavaDoc。下面看看使用Collectors對于代碼的簡化:

4.2 其他匯聚
– reduce方法:reduce方法非常的通用竭宰,后面介紹的count空郊,sum等都可以使用其實(shí)現(xiàn)。reduce方法有三個(gè)override的方法切揭,本文介紹兩個(gè)最常用的,最后一個(gè)留給讀者自己學(xué)習(xí)锁摔。先來看reduce方法的第一種形式廓旬,其方法定義如下:

Optional<T> reduce(BinaryOperator<T> accumulator);

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

List<Integer> 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è)值相加,得到的和會被賦值給下次執(zhí)行這個(gè)函數(shù)的第一個(gè)參數(shù)砸西。要注意的是:第一次執(zhí)行的時(shí)候第一個(gè)參數(shù)的值是Stream的第一個(gè)元素叶眉,第二個(gè)參數(shù)是Stream的第二個(gè)元素。這個(gè)方法返回值類型是Optional芹枷,這是Java8防止出現(xiàn)NPE的一種可行方法衅疙,后面的文章會詳細(xì)介紹,這里就簡單的認(rèn)為是一個(gè)容器鸳慈,其中可能會包含0個(gè)或者1個(gè)對象饱溢。這個(gè)過程可視化的結(jié)果如圖:

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

T reduce(T identity, BinaryOperator<T> accumulator);

這個(gè)定義上上面已經(jīng)介紹過的基本一致,不同的是:它允許用戶提供一個(gè)循環(huán)計(jì)算的初始值走芋,如果Stream為空绩郎,就直接返回該值。而且這個(gè)方法不會返回Optional翁逞,因?yàn)槠洳粫霈F(xiàn)null值肋杖。下面直接給出例子,就不再做說明了熄攘。

List<Integer> 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ù)兽愤。比較簡單,這里就直接給出例子,不做解釋了浅萧。

List<Integer> ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);
System.out.println("ints sum is:" + ints.stream().count());
  • 搜索相關(guān)
    allMatch:是不是Stream中的所有元素都滿足給定的匹配條件
    anyMatch:Stream中是否存在任何一個(gè)元素滿足匹配條件
    findFirst: 返回Stream中的第一個(gè)元素逐沙,如果Stream為空,返回空Optional
    noneMatch:是不是Stream中的所有元素都不滿足給定的匹配條件
    max和min:使用給定的比較器(Operator)洼畅,返回Stream中的最大|最小值

下面給出allMatch和max的例子旧烧,剩下的方法讀者當(dāng)成練習(xí)。

List<Integer> ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);
System.out.println(ints.stream().allMatch(item -> item < 100));
ints.stream().max((o1, o2) -> o1.compareTo(o2)).ifPresent(System.out::println);
  1. 下期預(yù)告

Functional Interface

  1. 引用文檔
  2. 《Java SE 8 for the Really Impatient》
  3. Java 8 API doc

原創(chuàng)文章拼苍,轉(zhuǎn)載請注明: 轉(zhuǎn)載自并發(fā)編程網(wǎng) – ifeve.com本文鏈接地址: Java8初體驗(yàn)(二)Stream語法詳解

  1. 下期預(yù)告
    Functional Interface
  2. 引用文檔
  3. 《Java SE 8 for the Really Impatient》2. Java 8 API doc

轉(zhuǎn)載自 Java8初體驗(yàn)(二)Stream語法詳解


KotlinChina編程社區(qū) 微博

《Kotlin極簡教程》正式上架:

點(diǎn)擊這里 > 去京東商城購買閱讀

點(diǎn)擊這里 > 去天貓商城購買閱讀

非常感謝 if (boy) { 帥氣英俊瀟灑} else { 魔鬼身材天使臉蛋美麗動(dòng)人女神氣質(zhì)} 的您来庭。大家請多支持!Iル取残揉!您的支持,是我源源不斷的寫作的動(dòng)力芋浮! 如果您有任何問題抱环,歡迎隨時(shí)與我交流~


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市纸巷,隨后出現(xiàn)的幾起案子镇草,更是在濱河造成了極大的恐慌,老刑警劉巖瘤旨,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梯啤,死亡現(xiàn)場離奇詭異,居然都是意外死亡存哲,警方通過查閱死者的電腦和手機(jī)因宇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宏胯,“玉大人羽嫡,你說我怎么就攤上這事〖缗郏” “怎么了杭棵?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氛赐。 經(jīng)常有香客問我魂爪,道長,這世上最難降的妖魔是什么艰管? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任滓侍,我火速辦了婚禮,結(jié)果婚禮上牲芋,老公的妹妹穿的比我還像新娘撩笆。我一直安慰自己捺球,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布夕冲。 她就那樣靜靜地躺著氮兵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歹鱼。 梳的紋絲不亂的頭發(fā)上泣栈,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音弥姻,去河邊找鬼南片。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庭敦,可吹牛的內(nèi)容都是我干的疼进。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼螺捐,長吁一口氣:“原來是場噩夢啊……” “哼颠悬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起定血,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诞外,沒想到半個(gè)月后澜沟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峡谊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年茫虽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片既们。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡濒析,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啥纸,到底是詐尸還是另有隱情号杏,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布斯棒,位于F島的核電站盾致,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荣暮。R本人自食惡果不足惜庭惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望穗酥。 院中可真熱鬧护赊,春花似錦惠遏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至器一,卻和暖如春课锌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祈秕。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工渺贤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人请毛。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓志鞍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親方仿。 傳聞我的和親對象是個(gè)殘疾皇子固棚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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

  • 1. Stream初體驗(yàn) 我們先來看看Java里面是怎么定義Stream的: A sequence of elem...
    kechao8485閱讀 1,236評論 0 9
  • Int Double Long 設(shè)置特定的stream類型, 提高性能仙蚜,增加特定的函數(shù) 無存儲此洲。stream不是一...
    patrick002閱讀 1,268評論 0 0
  • 轉(zhuǎn)自: Java 8 中的 Streams API 詳解 為什么需要 Stream Stream 作為 Java ...
    普度眾生的面癱青年閱讀 2,913評論 0 11
  • 這篇關(guān)于java stream的文章寫的特別好,轉(zhuǎn)載一下委粉,以備自己查看呜师。轉(zhuǎn)載自Java 8 中的 Streams ...
    小白小白啦閱讀 510評論 0 2
  • 終于等到大主宰的完結(jié)篇了汁汗。能堅(jiān)持看完大主宰,一是無書可看栗涂,二是想看結(jié)局知牌。 最開始看土豆的斗破蒼穹,整個(gè)劇情斤程、文筆角寸、...
    東坡串燒閱讀 446評論 2 2