恕我直言凰慈,我懷疑你沒怎么用過Stream流

簡書.jpg

文:恕我直言汞幢,我懷疑你沒怎么用過Stream流
注:中國傳統(tǒng)文化,先仔細(xì)看微谓,若有用森篷,再點(diǎn)贊, 給自己一點(diǎn)思考的時間
注:微信搜索:CodeCow豺型,關(guān)注這個非常 SAO 的程序員

我們是否一樣 仲智?

想當(dāng)年,小編在自學(xué)Java語言看書時姻氨,關(guān)于 “Stream流” 這一塊的知識點(diǎn)可能都有點(diǎn) “輕敵” 钓辆,覺得這塊內(nèi)容 “ so easy ”非常簡單,一眼而過肴焊。

d5fd2455a0c297c2e57c85fd2d9ad6ad - 副本.jpg

殊不知前联,撿了芝麻,丟了西瓜娶眷;并且在小編代碼中似嗤,也從未有過“Stream流” 地位可言;卻渾然不知届宠,java8的一哥“Stream流”双谆,在旁暗自嘲諷 “ 這TM是誰,太菜了 ” 席揽。

就拿小編上篇文章《兩年了顽馋,才知道如何實(shí)現(xiàn)多線程,哎 》來講幌羞,也是一堆連環(huán) for 循環(huán)的SAO操作寸谜,何曾想過Stream流的感受

java 8 一哥 ?

在Java 8中,得益于 Lambda 所帶 來的 函數(shù)式編程属桦,應(yīng)運(yùn)而生了一個全新的概念——Stream流熊痴,用于解決已有集合類庫既有的弊端他爸。

首先

關(guān)于Stream流上的操作,大體可以分為兩種:

  • 中間操作(Intermediate)果善,其返回結(jié)果都是Stream诊笤,故可以多個中間操作疊加;
  • 終止操作(Terminal)巾陕,其返回結(jié)果是我們最終需要的數(shù)據(jù)讨跟,故只能有一個終止操作

其次

Stream流是一個來自數(shù)據(jù)源的元素隊列,例如

  • 元素是特定類型的對象鄙煤,形成一個隊列晾匠。 Java中的Stream并不會存儲元素,而是按需計算梯刚。
  • 數(shù)據(jù)源 流的來源凉馆。 可以是集合,數(shù)組 等亡资。

再者

Stream流和以前的 Collection操作不同澜共, Stream操作還有兩個基礎(chǔ)的特征:

  • Pipelining:中間操作都會返回流對象本身。 這樣多個操作可以串聯(lián)成一個管道锥腻, 如同流式風(fēng)格(fluent style)咳胃。 這樣做可以對操作進(jìn)行優(yōu)化, 比如延遲執(zhí)行(laziness)短路( short-circuiting)旷太。
  • 內(nèi)部迭代: 以前對集合遍歷都是通過Iterator或者增強(qiáng)for的方式, 顯式的在集合外部進(jìn)行迭代展懈, 這叫做外部迭代。 Stream提供了內(nèi)部迭代的方式供璧,流可以直接調(diào)用遍歷方法存崖。

最后

嘍一眼Stream流的接口繼承關(guān)系
[圖片上傳失敗...(image-b7eb65-1596705940785)]

所以,當(dāng)我們使用一個流的時候睡毒,通常包括三個基本步驟:獲取一個數(shù)據(jù)源(source)→ 數(shù)據(jù)轉(zhuǎn)換→執(zhí)行操作獲取想要的結(jié)果

但来惧,每次轉(zhuǎn)換原有 Stream 對象不改變,返回一個新的 Stream 對象(可以有多次轉(zhuǎn)換)演顾,這就允許對其操作可以 像鏈條一樣排列供搀,變成一個管道。

注意:“Stream流”其實(shí)是一個集合元素的函數(shù)模型钠至,它并不是集合葛虐,也不是數(shù)據(jù)結(jié)構(gòu),其本身并不存儲任何 元素(或其地址值)棉钧。

因此屿脐,Stream流的一哥地位,并非空穴來風(fēng)

接下來,硬核SAO操作的诵,別眨眼
[圖片上傳失敗...(image-a750dd-1596705940785)]

為什么需要Stream流

常用的for循環(huán)它不香嗎万栅?為啥非得用Stream流?

舉個簡單的例子:

學(xué)生對象:

@Data
@AllArgsConstructor
public class Student {

    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "年齡")
    private Integer age;

    @ApiModelProperty(value = "性別(1-男西疤,2-女)")
    private Integer sex;
}

學(xué)生對象集合

public class StreamDemo {

    public static void main(String[] args) {
        // 測試數(shù)據(jù)
        List<Student> studentList = Lists.newArrayList();
        studentList.add(new Student("CodeCow", 18, 1));
        studentList.add(new Student("小明", 30, 1));
        studentList.add(new Student("小豬", 40, 2));
        studentList.add(new Student("小狗狗", 50, 2));
    }
}
        

假如烦粒,現(xiàn)有需求:篩選所有姓小的同學(xué),并且名字有三個字代赁,最后對結(jié)果進(jìn)行打印輸出

小編很幸運(yùn)扰她,曾見過這樣的SAO代碼,可謂 “猛龍過江”管跺,管你三七二十一义黎,上來先整幾個for循環(huán)再說禾进;

public static void main(String[] args) {

    //第一步:找出姓小的同學(xué)豁跑,放在list1 
    List<Student> list1 = Lists.newArrayList();
    for (Student student : studentList) {
        if (student.getName().startsWith("小")) {
            list1.add(student);
        }
    }
    //第二步:找出名字有三個字的同學(xué),放在list2
    List<Student> list2 = Lists.newArrayList();
    for (Student student : list1) {
        if (student.getName().length() == 3) {
            list2.add(student);
        }
    }
    //第三步:打印結(jié)果
    for (Student student : list2) {
        System.out.println(student);
    }
}

接下來泻云,我們Debug運(yùn)行下艇拍,看下結(jié)果:

Student(name=小狗狗, age=50, sex=2)

臥CAO,學(xué)生倒是賽選出來了宠纯,但是卸夕,現(xiàn)在賽選 條件只有三個,當(dāng)條件有幾十個時婆瓜,那幾十個for循環(huán)快集,不累嗎,那可以說是非常酸爽了……

再者廉白,你將Java 8 的一哥——stream流个初,至于何地
[圖片上傳失敗...(image-f0a1c5-1596705940785)]

體驗(yàn)哈Stream流的更優(yōu)寫法

大家肯定都知道Lambda吧,Java 8的Lambda讓我們可以更加專注于做什么(What)猴蹂,而不是怎么做(How)

這點(diǎn)小編也在上篇文章《兩年了院溺,才知道如何實(shí)現(xiàn)多線程,哎 》中結(jié)合“線程 + 匿名內(nèi)部類” 進(jìn)行了對比說明磅轻。有空可以看下

現(xiàn)在珍逸,我們體會下Stream流的優(yōu)雅:

public static void main(String[] args) {

   studentList.stream()
        .filter(i -> i.getName().startsWith("小"))//過濾出姓小的同學(xué)
        .filter(i -> i.getName().length() == 3) //過濾出名字有三個字的同學(xué)
        .forEach(System.out::println); //打印結(jié)果
}

再次Debug運(yùn)行下,看下結(jié)果:

Student(name=小狗狗, age=50, sex=2)

不難發(fā)現(xiàn)聋溜,區(qū)區(qū)3行代碼谆膳,運(yùn)行結(jié)果也一樣;同時撮躁,順帶解決了上面的SAO操作摹量, 他不香嗎?

總結(jié)下,為什么很香

  • 第一點(diǎn):可以清楚地知道我們要對一個數(shù)據(jù)集做何種操作缨称,可讀性賊強(qiáng)(就三行凝果,讀不明白 ?)
  • 第二點(diǎn):可以很輕松地獲取并行化Stream流睦尽,不用自己編寫多線程代碼(阿牛上篇文章就是最好的證明F骶弧!)
  • 第三點(diǎn):可以讓我們更加專注于業(yè)務(wù)邏輯 (還用考慮用幾個for循環(huán)嗎5狈病山害!)。

簡而言之沿量,Stream浪慌,愛了,愛了

在這里插入圖片描述

您也為這就是Stream流的全部嗎朴则,“No权纤,No,No

接下來乌妒,咋們看下Stream流 風(fēng)SAO 集合

了解下Stream流更多SAO操作

需求1:獲取姓小同學(xué)的集合

public static void main(String[] args) {

    List<Student> list = studentList.stream()
        .filter(i -> i.getName().startsWith("小"))
        .collect(Collectors.toList());
}

結(jié)果為:

[
Student(name=小明, age=30, sex=1), 
Student(name=小豬, age=40, sex=2), 
Student(name=小狗狗, age=50, sex=2)
]

需求2:獲取姓小的同學(xué)汹想,并且年齡大于30的集合

public static void main(String[] args) {

    List<Student> list = studentList.stream()
        .filter(i -> i.getName().startsWith("小") && i.getAge() >30)
        .collect(Collectors.toList());
}

結(jié)果為:

[
Student(name=小豬, age=40, sex=2), 
Student(name=小狗狗, age=50, sex=2)
]

需求3:獲取姓名為“小明”的同學(xué),的集合

public static void main(String[] args) {

    List<Student> list = studentList.stream()
        .filter(i -> i.getName().equals("小明"))
        .collect(Collectors.toList());
}

結(jié)果為:

[Student(name=小明, age=40, sex=1)]

需求4:獲取所有同學(xué)姓名的集合

public static void main(String[] args) {

    List<String> list = studentList.stream()
        .map(Student::getName)
        .collect(Collectors.toList());
}

結(jié)果為:

[CodeCow, 小明, 小豬, 小狗狗]

需求5:根據(jù)學(xué)生年齡進(jìn)行升序排序

public static void main(String[] args) {

    List<Student> list = studentList.stream()
        .sorted(Comparator.comparing(Student::getAge))
        .collect(Collectors.toList());
}

結(jié)果為:

[
Student(name=CodeCow, age=18, sex=1), 
Student(name=小明, age=40, sex=1), 
Student(name=小豬, age=50, sex=2), 
Student(name=小狗狗, age=50, sex=2)
]

需求6:根據(jù)學(xué)生年齡進(jìn)行降序排序

public static void main(String[] args) {

    List<Student> list = studentList.stream()
        .sorted(Comparator.comparing(Student::getAge).reversed())
        .collect(Collectors.toList());
}

結(jié)果為:

[
Student(name=小豬, age=50, sex=2), 
Student(name=小狗狗, age=50, sex=2), 
Student(name=小明, age=40, sex=1), 
Student(name=CodeCow, age=18, sex=1)
]

需求7:distinct 去重

public static void main(String[] args) {

    List<Integer> integers = Lists.list(30, 40, 10, 20, 20, 10, 50, 20);
    List<Integer> collect = 
            integers.stream().distinct().collect(Collectors.toList());
    System.out.println(collect);//[30, 40, 10, 20, 50] 去重結(jié)果
}

需求8:找最小值 min撤蚊,總數(shù)量 count

public static void main(String[] args) {

    List<Integer> integers = Lists.list(30, 40, 10, 20, 20, 10, 50, 20);
    Integer integer1 = integers.stream().min(Integer::compareTo).orElse(-1);
        System.out.println(integer1); //10 最小值
        long count = integers.stream().count();
        System.out.println(count);//8 總數(shù)量
}

淺聊 Java 8 Stream 流古掏,今就到這,下文見 _

在這里插入圖片描述

后記

好啦侦啸,今就先聊到這里吧槽唾,本文僅僅是 拋磚引玉 而已,使用了 Java 8 Stream流 和大家聊了聊光涂,打了個樣庞萍;且并非Stream流所有特性,這只是其 冰山一角顶捷;下文見

★★ 好文推薦 ★★

小聲BB

  • 中國傳統(tǒng)文化葵蒂,先仔細(xì)看,若有用重虑,再點(diǎn)贊践付, 給自己一點(diǎn)思考的時間
  • 更多幽默、風(fēng)趣好文缺厉,盡在“ CodeCow ” , WX搜索 CodeCow永高,可以看看

《 Java如海隧土,學(xué)習(xí)作舟,泛舟于海命爬,方知Java之寬闊 》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曹傀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子饲宛,更是在濱河造成了極大的恐慌皆愉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艇抠,死亡現(xiàn)場離奇詭異幕庐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)家淤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門异剥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人絮重,你說我怎么就攤上這事冤寿。” “怎么了绿鸣?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵疚沐,是天一觀的道長暂氯。 經(jīng)常有香客問我潮模,道長,這世上最難降的妖魔是什么痴施? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任擎厢,我火速辦了婚禮,結(jié)果婚禮上辣吃,老公的妹妹穿的比我還像新娘动遭。我一直安慰自己,他們只是感情好神得,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布厘惦。 她就那樣靜靜地躺著,像睡著了一般哩簿。 火紅的嫁衣襯著肌膚如雪宵蕉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天节榜,我揣著相機(jī)與錄音羡玛,去河邊找鬼。 笑死宗苍,一個胖子當(dāng)著我的面吹牛稼稿,可吹牛的內(nèi)容都是我干的薄榛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼让歼,長吁一口氣:“原來是場噩夢啊……” “哼敞恋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谋右,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤耳舅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倚评,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浦徊,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年天梧,在試婚紗的時候發(fā)現(xiàn)自己被綠了盔性。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呢岗,死狀恐怖冕香,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情后豫,我是刑警寧澤悉尾,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站挫酿,受9級特大地震影響构眯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜早龟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一惫霸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧葱弟,春花似錦壹店、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至藏杖,卻和暖如春将塑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背制市。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工抬旺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人祥楣。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓开财,卻偏偏與公主長得像汉柒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子责鳍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353