Java8_初識(shí)流(Stream)

Java8中新增的特性中谈山,對(duì)核心類庫(kù)的改進(jìn)是很關(guān)鍵的一部分榛瓮,這部分主要包括了集合類的API和新引入的流(Stream),流使得我們可以站在更高的抽象層次上對(duì)集合進(jìn)行操作,下面我們就來熟悉一下什么是流爬橡。

 Stream<String> stream1 = Stream.of("hello", "world", "hello world");

這樣就創(chuàng)建了一個(gè)流,如果我們要找到流中字符串長(zhǎng)度小于6的字符串個(gè)數(shù)友绝,我們可以這樣寫

long count = stream1.filter(item -> item.length() < 6).count();//2

可以看到我們用了兩步來求值
1.filter(item -> item.length() < 6)過濾字符串長(zhǎng)度小于6
2.count() 計(jì)算數(shù)量
看起來像是進(jìn)行了兩次循環(huán)堤尾,其實(shí)不然

 stream1.filter(item -> item.length() < 6)

這行代碼并未做什么實(shí)質(zhì)性的工作,只是描述了Stream迁客,我們可以測(cè)試一下

stream1.filter(item ->{
                System.out.println("filter");
                return item.length() < 6;
                }
            );

運(yùn)行程序郭宝,發(fā)現(xiàn)并沒有打印任何東西,我們繼續(xù)加上count看一下

 stream1.filter(item ->{
                System.out.println("filter");
                return item.length() < 6;  
                }
            ).count();

這時(shí)打印出了

filter
filter
filter

之所以是這樣掷漱,是因?yàn)榱鞑僮鞣譃閮深悾?br> 1.惰性求值:返回一個(gè)Stream
2.及早求值:返回具體的值

一個(gè)流操作有三部分組成:
1.源
2.零個(gè)或多個(gè)中間操作
3.終止操作
在執(zhí)行終止操作前粘室,流中間的多個(gè)操作都不會(huì)運(yùn)行,只有當(dāng)執(zhí)行了終止操作后卜范,流才會(huì)根據(jù)所有的條件去綜合執(zhí)行衔统。

常用的流操作


  1. collect(toList())
    collect(toList())是由Stream里的值生成一個(gè)列表,是一個(gè)及早求值操作海雪。
List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
list.forEach(System.out::print);//abc  
  1. map
    將一個(gè)流中的值轉(zhuǎn)換成一個(gè)新的流
    Java8之前如果我們要將一個(gè)列表中的字符串轉(zhuǎn)換成大寫锦爵,要這樣寫
List<String> newList = new ArrayList();
List<String> list = Arrays.asList("a", "b", "c");
for (String str : list) {
    newList.add(str.toUpperCase());
}
newList.forEach(System.out::print);//ABC

使用map我們只需要這樣寫,map所接收的Lambda表達(dá)式必須是一個(gè)Function接口的一個(gè)實(shí)例奥裸。

List<String> list = Arrays.asList("a", "b", "c");
List<String> newList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
newList.forEach(System.out::print);//ABC

在Stream中對(duì)原生類型的map操作進(jìn)行了幾個(gè)擴(kuò)展险掀,有mapToInt、mapToLong湾宙、mapToDouble樟氢,所以在進(jìn)行具體使用的時(shí)候最好具體指定具體類型的方法冈绊,這樣可以避免自動(dòng)裝箱拆箱帶來的損耗

Stream.iterate(1,item-> item+2).limit(6).filter(value -> value>200).mapToInt(value -> value * 2).skip(2).limit(2).min().ifPresent(System.out::print);
  1. filter
    這個(gè)在最上面也講過了,filter接收的Lambda表達(dá)式必須是一個(gè)Predicate接口的一個(gè)實(shí)例。
Stream<String> stream1 = Stream.of("hello", "world", "hello world");
long count = stream1.filter(item -> item.length() < 6).count();
System.out.println(count);
  1. flatMap
    flatMap方法可用Stream替換值埠啃,然后將多個(gè)Stream連接成一個(gè)Stream
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

假設(shè)有一個(gè)包含多個(gè)列表的流死宣,現(xiàn)在要得到所有數(shù)字的序列

Stream<List<Integer>> stream = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4), Arrays.asList(5, 6, 7));
List<Integer> list = stream.flatMap(item->item.stream()).collect(Collectors.toList());
System.out.println(list);//[1, 2, 3, 4, 5, 6, 7]
  1. max和min
    求最大最小值是很常用的操作,方法接收一個(gè)Comparator對(duì)象碴开,Java8提供了一個(gè)新的靜態(tài)方法comparing毅该,該方法接收一個(gè)函數(shù),返回一個(gè)函數(shù)潦牛,max方法返回的是一個(gè)Optional對(duì)象
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
list.stream().max(Comparator.comparing(item -> item)).ifPresent(System.out::println);//7

6.reduce
max和min都屬于一種通用的編程模式鹃骂,這種模式可以用以下偽代碼體現(xiàn):

Object accumulator = initialValue;
for(Object element : collection){
        accumulator = combine(accumulator,element);
}

首先賦給accumulator一個(gè)初始值:initialValue,然后在循環(huán)體中罢绽,通過調(diào)用combine函數(shù),拿accumulator和集合中的每一個(gè)元素做運(yùn)算静盅,再將運(yùn)算結(jié)果賦給accumulator良价,最后accumulator的值就是想要的結(jié)果。

上面例子中用到的count蒿叠、max明垢、min方法,其實(shí)都是reduce操作市咽,因?yàn)槌S盟员患{入標(biāo)準(zhǔn)庫(kù)中痊银。

來看幾個(gè)例子
求和:

int count = Arrays.asList(1, 2, 3).stream().reduce(0,(acc,item)->acc+item);
System.out.println(count);//6

求最大值:

 List<Integer> list2 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
list2.stream().reduce((maxitem,item)->{
           System.out.println("maxitem:"+maxitem + "item:"+item);
            if(maxitem < item){
                return item;
            }else{
                return maxitem;
            }
        }).ifPresent(System.out::println);//7

log打印:

maxitem:1item:2
maxitem:2item:3
maxitem:3item:4
maxitem:4item:5
maxitem:5item:6
maxitem:6item:7

可以看出reduce執(zhí)行的邏輯施绎,上面程序是為了看內(nèi)部實(shí)現(xiàn)溯革,其實(shí)可以簡(jiǎn)短的寫成

list2.stream().reduce(BinaryOperator.maxBy(Comparator.comparingInt(Integer::new))).ifPresent(System.out::println);

總結(jié)

本次主要介紹了Stream的基本概念以及用法,作為一個(gè)初步了解谷醉,關(guān)于Stream還有著更加復(fù)雜的操作以及一些陷阱致稀,后續(xù)我們?cè)僦鸩椒治觥?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俱尼,隨后出現(xiàn)的幾起案子抖单,更是在濱河造成了極大的恐慌,老刑警劉巖遇八,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矛绘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡刃永,警方通過查閱死者的電腦和手機(jī)货矮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揽碘,“玉大人次屠,你說我怎么就攤上這事园匹。” “怎么了劫灶?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵裸违,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我本昏,道長(zhǎng)供汛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任涌穆,我火速辦了婚禮怔昨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宿稀。我一直安慰自己趁舀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布祝沸。 她就那樣靜靜地躺著矮烹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罩锐。 梳的紋絲不亂的頭發(fā)上奉狈,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音涩惑,去河邊找鬼仁期。 笑死,一個(gè)胖子當(dāng)著我的面吹牛竭恬,可吹牛的內(nèi)容都是我干的跛蛋。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼痊硕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼问芬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寿桨,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤此衅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后亭螟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挡鞍,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年预烙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了墨微。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扁掸,死狀恐怖翘县,靈堂內(nèi)的尸體忽然破棺而出最域,到底是詐尸還是另有隱情,我是刑警寧澤锈麸,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布镀脂,位于F島的核電站,受9級(jí)特大地震影響忘伞,放射性物質(zhì)發(fā)生泄漏薄翅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一氓奈、第九天 我趴在偏房一處隱蔽的房頂上張望翘魄。 院中可真熱鬧,春花似錦舀奶、人聲如沸暑竟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)光羞。三九已至,卻和暖如春怀大,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呀闻。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工化借, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捡多。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓蓖康,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親垒手。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蒜焊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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

  • Jav8中,在核心類庫(kù)中引入了新的概念科贬,流(Stream)泳梆。流使得程序媛們得以站在更高的抽象層次上對(duì)集合進(jìn)行操作。...
    仁昌居士閱讀 3,625評(píng)論 0 6
  • Java8 in action 沒有共享的可變數(shù)據(jù)榜掌,將方法和函數(shù)即代碼傳遞給其他方法的能力就是我們平常所說的函數(shù)式...
    鐵牛很鐵閱讀 1,223評(píng)論 1 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理优妙,服務(wù)發(fā)現(xiàn),斷路器憎账,智...
    卡卡羅2017閱讀 134,638評(píng)論 18 139
  • 了解Stream ? Java8中有兩個(gè)最為重要的改變套硼,一個(gè)是Lambda表達(dá)式,另一個(gè)就是Stream AP...
    龍歷旗閱讀 3,306評(píng)論 3 4
  • 原文地址: http://cr.openjdk.java.net/~briangoetz/lambda/lambd...
    mualex閱讀 616評(píng)論 0 0