【java8新特性 簡述】Stream API

java8的又一特性就是 流(Stream),流主要是對數(shù)據(jù)源(集合缠借、數(shù)組等)的一種處理方式干毅,有高效的聚合操作、大批量的數(shù)據(jù)處理泼返,同時也內(nèi)置了許多運(yùn)算方式硝逢,包括篩選、排序绅喉、聚合等 渠鸽,特別提醒:流運(yùn)用了大量的lambda表達(dá)式。 這里只是列出一些常用的知識點(diǎn)柴罐,幫助你快速了解它徽缚。

幾大特點(diǎn)

  1. 與lambda表達(dá)式結(jié)合,代碼極簡丽蝎,可讀性高
  2. 提供并行操作猎拨,充分發(fā)揮多核處理器優(yōu)勢
  3. 進(jìn)行并行操作,無需額外編寫多線程代碼即可實(shí)現(xiàn)高效并發(fā)程序屠阻,規(guī)避多線程代碼問題

簡單基本概念

  • 元素 流Stream是來自數(shù)據(jù)源的元素隊(duì)列红省,本身不具備元素
  • 數(shù)據(jù)源 包括包含集合、數(shù)組国觉、I/O channel吧恃、generator(發(fā)生器)等
  • 聚合操作 類似SQL中的filter、map麻诀、find痕寓、match、sorted等操作
  • 管道運(yùn)算 Stream在Pipeline中運(yùn)算后返回Stream對象本身蝇闭,這樣多個操作串聯(lián)成一個Pipeline呻率,并形成fluent風(fēng)格的代碼。這種方式可以優(yōu)化操作呻引,如延遲執(zhí)行(laziness)和短路( short-circuiting)礼仗。(我理解為鏈?zhǔn)讲僮?
  • 內(nèi)部迭代 不同于java8以前對集合的遍歷方式(外部迭代),采用訪問者模式(Visitor)實(shí)現(xiàn)了內(nèi)部迭代逻悠。
  • 并行運(yùn)算 Stream API支持串行(stream() )或并行(parallelStream() )的兩種操作方式元践。

簡單實(shí)例

  • java8之前
public static void main(String[] args)
    {  
        List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        long count = 0;
        
        for(Integer number: numbers)
        {
            if(number > 0)
            {
                count++;
            }
        }
        
        System.out.println("Positive count: " + count);
    }

通常利用for循環(huán)遍歷

  • java8之后
public static void main(String[] args)
    {  
        List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);
      
        long count = numbers.parallelStream().filter(i -> i>0).count();
        
        System.out.println("Positive count: " + count);
    }

上例中,使用filter()方法對數(shù)組進(jìn)行了過濾童谒,使用count()方法對過濾后的數(shù)組進(jìn)行了大小統(tǒng)計(jì)单旁,且使parallelStream()方法為集合創(chuàng)建了并行流,自動采用并行運(yùn)算提高速度饥伊。在更復(fù)雜的場景象浑,還可以用forEach()蔫饰、map()、limit()融柬、sorted()死嗦、collect()等方法進(jìn)行進(jìn)一步的流運(yùn)算。
并且 通常會和lambda表達(dá)式一起使用粒氧,使得代碼更加優(yōu)雅越除。

常用接口

  • Stream的生成( 串行流 : stream(); 并行流 : parallelStream()
List list = new ArrayList();
list.stream().//接下來管道操作
  • forEach()方法 (用來迭代流中的每一個數(shù)據(jù))
List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);
numbers.stream().forEach(n ->  System.out.println("List element: " + n));
  • map()方法 (將流中的所有元素用Function對象進(jìn)行運(yùn)算外盯,生成新的流對象)
List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);        
 numbers.stream().map( n -> Math.abs(n)).forEach(n ->  System.out.println("Element abs: " + n));
  • flatMap()方法 (比map()方法擁有更高的映射深度)

用flatMap()方法如下:

List<String> list = Arrays.asList("1 2", "3 4", "5 6");
list.stream().flatMap(item -> Arrays.stream(item.split(" "))).forEach(System.out::println);

而用map()方法:

List<String> list = Arrays.asList("1 2", "3 4", "5 6");
list.stream().map(item -> Arrays.stream(item.split(" "))).forEach(n ->n.forEach(System.out::println));

可見摘盆,用map()方法,返回了一個“流中流”饱苟,需要在每個Stream元素遍歷時孩擂,再加一層forEach進(jìn)行遍歷。

  • filter()方法 (過濾)
List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);      
long count = numbers.parallelStream().filter(i -> i>0).count();        
System.out.println("Positive count: " + count);
  • reduce()方法 (為折疊操作箱熬,用于將流中的所有值合成一個)
List<Integer> numbers = Arrays.asList(-1, -2, 0, -1, 4, 5, 1);        
 Integer total = numbers.stream().reduce((t, n) -> t + n).get();        
System.out.println("Total: " + total);
  • collect()方法 (將流轉(zhuǎn)為數(shù)據(jù)源 (集合等))
    collect()方法的參數(shù)為一個java.util.stream.Collector類型對象类垦,可以用java.util.stream.Collectors工具類提供的靜態(tài)方法來生成,Collectors類實(shí)現(xiàn)很多的歸約操作城须,如Collectors.toList()蚤认、Collectors.toSet()、Collectors.joining()(joining適用于字符串流)等
List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);        
List<Integer> abss = numbers.stream().map( n -> Math.abs(n)).collect(Collectors.toList());
 System.out.println("Abs list: " + abss);
  • 數(shù)值操作的方法
    Stream采用mapToInt()糕伐、mapToLong()砰琢、mapToDouble()三個方法分別生成IntStream 、LongStream 良瞧、DoubleStream 三個接口類型的對象
    IntStream 陪汽、LongStream 、DoubleStream 三個接口類型都有一個summaryStatistics()方法褥蚯,其中挚冤,
    IntStream 的方法是:IntSummaryStatistics summaryStatistics();
    LongStream 的方法是:LongSummaryStatistics summaryStatistics();
    DoubleStream 的方法是:DoubleSummaryStatistics summaryStatistics();
    IntSummaryStatistics、LongSummaryStatistics 赞庶、DoubleSummaryStatistics三個接口類型(位于java.util包下)中训挡,都有諸如統(tǒng)計(jì)數(shù)量、最大值尘执、最小值、求和宴凉、平均值等方法(方法名和返回類型可能不同),可以方便的進(jìn)行數(shù)值統(tǒng)計(jì)誊锭。

看這么多文字,還是來個例子消化比較好:

List<Integer> numbers = Arrays.asList(-1, -2, 0, 4, 5);        
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();        
System.out.println("Max : " + stats.getMax());
System.out.println("Min : " + stats.getMin());
System.out.println("Sum : " + stats.getSum());
System.out.println("Average : " + stats.getAverage());
System.out.println("Count : " + stats.getCount());
  • 其它方法
    Stream API還有一些其它的方法弥锄,比如:
        limit()    獲取指定數(shù)量的流
        sorted()   對流進(jìn)行排序
        distinct()  去重
        skip()    跳過指定數(shù)量的元素
        peek()   生成一個包含原Stream的所有元素的新Stream丧靡,并指定消費(fèi)函數(shù)
        count()   計(jì)算元素?cái)?shù)量

這部分只是流stream的冰山一角蟆沫,想要深入的朋友可以去看下java8的關(guān)于流這部分的源碼,進(jìn)行深入學(xué)習(xí)温治。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饭庞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子熬荆,更是在濱河造成了極大的恐慌舟山,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卤恳,死亡現(xiàn)場離奇詭異累盗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)突琳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門若债,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拆融,你說我怎么就攤上這事蠢琳。” “怎么了镜豹?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵傲须,是天一觀的道長。 經(jīng)常有香客問我逛艰,道長躏碳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任散怖,我火速辦了婚禮菇绵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镇眷。我一直安慰自己咬最,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布欠动。 她就那樣靜靜地躺著永乌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪具伍。 梳的紋絲不亂的頭發(fā)上翅雏,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音人芽,去河邊找鬼望几。 笑死,一個胖子當(dāng)著我的面吹牛萤厅,可吹牛的內(nèi)容都是我干的橄抹。 我是一名探鬼主播靴迫,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼楼誓!你這毒婦竟也來了玉锌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疟羹,失蹤者是張志新(化名)和其女友劉穎主守,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阁猜,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丸逸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了剃袍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黄刚。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖民效,靈堂內(nèi)的尸體忽然破棺而出憔维,到底是詐尸還是另有隱情,我是刑警寧澤畏邢,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布业扒,位于F島的核電站,受9級特大地震影響舒萎,放射性物質(zhì)發(fā)生泄漏程储。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一臂寝、第九天 我趴在偏房一處隱蔽的房頂上張望章鲤。 院中可真熱鬧,春花似錦咆贬、人聲如沸败徊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皱蹦。三九已至,卻和暖如春眷蜈,著一層夾襖步出監(jiān)牢的瞬間沪哺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工酌儒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辜妓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像嫌拣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子呆躲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

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

  • 歡迎交流java8新特性系列文章:http://www.reibang.com/nb/27231419 . [...
    DoubleBin閱讀 15,083評論 0 41
  • 原文地址: 深藍(lán)至尊 一. 流式處理簡介 在我接觸到j(luò)ava8流式處理的時候插掂,我的第一感覺是流式處理讓集合操作變得...
    咻咻咻i閱讀 1,147評論 0 0
  • Java8 in action 沒有共享的可變數(shù)據(jù)灰瞻,將方法和函數(shù)即代碼傳遞給其他方法的能力就是我們平常所說的函數(shù)式...
    鐵牛很鐵閱讀 1,229評論 1 2
  • 轉(zhuǎn)自: Java 8 中的 Streams API 詳解 為什么需要 Stream Stream 作為 Java ...
    普度眾生的面癱青年閱讀 2,918評論 0 11
  • 學(xué)習(xí) 1.聽了兩篇得到,有幾個有意思的點(diǎn)聽進(jìn)來: 第一辅甥,根據(jù)計(jì)算機(jī)的運(yùn)算原理酝润,大項(xiàng)目的最好處理方式是拆分成N個小項(xiàng)...
    NancyLuo閱讀 126評論 0 0