溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java的Stream?API終端操作示例分析

發(fā)布時(shí)間:2022-03-17 09:05:39 來(lái)源:億速云 閱讀:131 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“java的Stream API終端操作示例分析”,在日常操作中,相信很多人在java的Stream API終端操作示例分析問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”java的Stream API終端操作示例分析”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

    一、Java Stream管道數(shù)據(jù)處理操作

    在本號(hào)之前寫(xiě)過(guò)的文章中,曾經(jīng)給大家介紹過(guò) Java Stream管道流是用于簡(jiǎn)化集合類(lèi)元素處理的java API。在使用的過(guò)程中分為三個(gè)階段。在開(kāi)始本文之前,我覺(jué)得仍然需要給一些新朋友介紹一下這三個(gè)階段,如圖:

    java的Stream?API終端操作示例分析

    • 第一階段(圖中藍(lán)色):將集合、數(shù)組、或行文本文件轉(zhuǎn)換為java Stream管道流

    • 第二階段(圖中虛線部分):管道流式數(shù)據(jù)處理操作,處理管道中的每一個(gè)元素。上一個(gè)管道中的輸出元素作為下一個(gè)管道的輸入元素。

    • 第三階段(圖中綠色):管道流結(jié)果處理操作,也就是本文的將介紹的核心內(nèi)容。

    在開(kāi)始學(xué)習(xí)之前,仍然有必要回顧一下我們之前給大家講過(guò)的一個(gè)例子:

    List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
    List<String> list = nameStrs.stream()
            .filter(s -> s.startsWith("L"))
            .map(String::toUpperCase)
            .sorted()
            .collect(toList());
    System.out.println(list);

    首先使用stream()方法將字符串List轉(zhuǎn)換為管道流Stream

    然后進(jìn)行管道數(shù)據(jù)處理操作,先用fliter函數(shù)過(guò)濾所有大寫(xiě)L開(kāi)頭的字符串,然后將管道中的字符串轉(zhuǎn)換為大寫(xiě)字母toUpperCase,然后調(diào)用sorted方法排序。這些API的用法在本號(hào)之前的文章有介紹過(guò)。其中還使用到了lambda表達(dá)式和函數(shù)引用。

    最后使用collect函數(shù)進(jìn)行結(jié)果處理,將java Stream管道流轉(zhuǎn)換為L(zhǎng)ist。最終list的輸出結(jié)果是:[LEMUR, LION]

    如果你不使用java Stream管道流的話,想一想你需要多少行代碼完成上面的功能呢?回到正題,這篇文章就是要給大家介紹第三階段:對(duì)管道流處理結(jié)果都可以做哪些操作呢?下面開(kāi)始吧!

    二、ForEach和ForEachOrdered

    如果我們只是希望將Stream管道流的處理結(jié)果打印出來(lái),而不是進(jìn)行類(lèi)型轉(zhuǎn)換,我們就可以使用forEach()方法或forEachOrdered()方法。

    Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
            .parallel()
            .forEach(System.out::println);
    Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
            .parallel()
            .forEachOrdered(System.out::println);

    parallel()函數(shù)表示對(duì)管道中的元素進(jìn)行并行處理,而不是串行處理,這樣處理速度更快。但是這樣就有可能導(dǎo)致管道流中后面的元素先處理,前面的元素后處理,也就是元素的順序無(wú)法保證

    forEachOrdered從名字上看就可以理解,雖然在數(shù)據(jù)處理順序上可能無(wú)法保障,但是forEachOrdered方法可以在元素輸出的順序上保證與元素進(jìn)入管道流的順序一致。也就是下面的樣子(forEach方法則無(wú)法保證這個(gè)順序):

    Monkey
    Lion
    Giraffe
    Lemur
    Lion

    三、元素的收集collect

    java Stream 最常見(jiàn)的用法就是:一將集合類(lèi)轉(zhuǎn)換成管道流,二對(duì)管道流數(shù)據(jù)處理,三將管道流處理結(jié)果在轉(zhuǎn)換成集合類(lèi)。那么collect()方法就為我們提供了這樣的功能:將管道流處理結(jié)果在轉(zhuǎn)換成集合類(lèi)。

    3.1.收集為Set

    通過(guò)Collectors.toSet()方法收集Stream的處理結(jié)果,將所有元素收集到Set集合中。

    Set<String> collectToSet = Stream.of(
       "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    ) 
    .collect(Collectors.toSet());
    //最終collectToSet 中的元素是:[Monkey, Lion, Giraffe, Lemur],注意Set會(huì)去重。

    3.2.收集到List

    同樣,可以將元素收集到List使用toList()收集器中。

    List<String> collectToList = Stream.of(
       "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    ).collect(Collectors.toList());
    
    // 最終collectToList中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]

    3.3.通用的收集方式

    上面為大家介紹的元素收集方式,都是專(zhuān)用的。比如使用Collectors.toSet()收集為Set類(lèi)型集合;使用Collectors.toList()收集為L(zhǎng)ist類(lèi)型集合。那么,有沒(méi)有一種比較通用的數(shù)據(jù)元素收集方式,將數(shù)據(jù)收集為任意的Collection接口子類(lèi)型。 所以,這里就像大家介紹一種通用的元素收集方式,你可以將數(shù)據(jù)元素收集到任意的Collection類(lèi)型:即向所需Collection類(lèi)型提供構(gòu)造函數(shù)的方式。

    LinkedList<String> collectToCollection = Stream.of(
       "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    ).collect(Collectors.toCollection(LinkedList::new));
    //最終collectToCollection中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]

    注意:代碼中使用了LinkedList::new,實(shí)際是調(diào)用LinkedList的構(gòu)造函數(shù),將元素收集到Linked List。當(dāng)然你還可以使用諸如LinkedHashSet::newPriorityQueue::new將數(shù)據(jù)元素收集為其他的集合類(lèi)型,這樣就比較通用了。

    3.4.收集到Array

    通過(guò)toArray(String[]::new)方法收集Stream的處理結(jié)果,將所有元素收集到字符串?dāng)?shù)組中。

    String[] toArray = Stream.of(
       "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    ) .toArray(String[]::new);
    //最終toArray字符串?dāng)?shù)組中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]

    3.5.收集到Map

    使用Collectors.toMap()方法將數(shù)據(jù)元素收集到Map里面,但是出現(xiàn)一個(gè)問(wèn)題:那就是管道中的元素是作為key,還是作為value。我們用到了一個(gè)Function.identity()方法,該方法很簡(jiǎn)單就是返回一個(gè)“ t -> t ”(輸入就是輸出的lambda表達(dá)式)。另外使用管道流處理函數(shù)distinct()來(lái)確保Map鍵值的唯一性。

    Map<String, Integer> toMap = Stream.of(
        "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    )
    .distinct()
    .collect(Collectors.toMap(
           Function.identity(),   //元素輸入就是輸出,作為key
           s -> (int) s.chars().distinct().count()// 輸入元素的不同的字母?jìng)€(gè)數(shù),作為value
    ));
    // 最終toMap的結(jié)果是: {Monkey=6, Lion=4, Lemur=5, Giraffe=6}

    3.6.分組收集groupingBy

    Collectors.groupingBy用來(lái)實(shí)現(xiàn)元素的分組收集,下面的代碼演示如何根據(jù)首字母將不同的數(shù)據(jù)元素收集到不同的List,并封裝為Map。

    Map<Character, List<String>> groupingByList =  Stream.of(
        "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
    )
    .collect(Collectors.groupingBy(
           s -> s.charAt(0) ,  //根據(jù)元素首字母分組,相同的在一組
           // counting()        // 加上這一行代碼可以實(shí)現(xiàn)分組統(tǒng)計(jì)
    ));
    // 最終groupingByList內(nèi)的元素: {G=[Giraffe], L=[Lion, Lemur, Lion], M=[Monkey]}
    //如果加上counting() ,結(jié)果是:  {G=1, L=3, M=1}

    這是該過(guò)程的說(shuō)明:groupingBy第一個(gè)參數(shù)作為分組條件,第二個(gè)參數(shù)是子收集器。

    四、其他常用方法

    boolean containsTwo = IntStream.of(1, 2, 3).anyMatch(i -> i == 2);
    // 判斷管道中是否包含2,結(jié)果是: true
    long nrOfAnimals = Stream.of(
        "Monkey", "Lion", "Giraffe", "Lemur"
    ).count();
    // 管道中元素?cái)?shù)據(jù)總計(jì)結(jié)果nrOfAnimals: 4
    int sum = IntStream.of(1, 2, 3).sum();
    // 管道中元素?cái)?shù)據(jù)累加結(jié)果sum: 6
    OptionalDouble average = IntStream.of(1, 2, 3).average();
    //管道中元素?cái)?shù)據(jù)平均值average: OptionalDouble[2.0]
    int max = IntStream.of(1, 2, 3).max().orElse(0);
    //管道中元素?cái)?shù)據(jù)最大值max: 3
    IntSummaryStatistics statistics = IntStream.of(1, 2, 3).summaryStatistics();
    // 全面的統(tǒng)計(jì)結(jié)果statistics: IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}

    到此,關(guān)于“java的Stream API終端操作示例分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI