欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 流的高級使用之收集數據解析

 更新時間:2021年08月25日 09:49:57   作者:FXBStudy  
這篇文章主要介紹了Java 流的高級使用之收集數據解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、前言

1.1 收集器

收集器的接口是java.util.stream.Collector,我們只需要調用流的collect方法并傳遞給一個Collector接口的一個實現(也就是給Stream中元素做匯總的方法),就可以了。例如java.util.stream.Collectors類的toList()方法,該方法就會返回一個按順序給每個元素生成一個列表的Collector接口的實現。

收集器非常有用,因為它可以簡介而靈活地定義collect用來生成結果集合的標準。更具體地說,對流調用collect方法將對流中的元素觸發(fā)一個規(guī)約操作(由Collector來參數化)。

1.2 預定義收集器

JDK為我們提供了java.util.stream.Collectors類,其為我們提供了很多靜態(tài)工廠方法,可以方便地創(chuàng)建常見的收集器實例,而我們只要拿來用就可以了。最直接和最常用的收集器是toList靜態(tài)方法,它會把流中所有的元素收集到一個List中。

Collectors類為我們提供的收集器,主要包含三大功能:

  • 將流元素規(guī)約和匯總為一個值
  • 元素分組
  • 元素分區(qū)

注意:因為其為我們提供的都是靜態(tài)方法,我們可以通過靜態(tài)導入的方式簡化代碼的書寫。

二、深入

2.1 規(guī)約和匯總

統(tǒng)計元素數量

Collectors為我們提供了counting方法,為我們提供了統(tǒng)計元素數量的收集器。實例:

long howManyDishes = menu.stream().collect(Collectors.counting());

上面的示例是利用預定義收集器實現的,其實Stream接口定義了count方法,因此我們也可以直接調用Stream提供的預定義方法來實現,如下:

long howManyDishes = menu.stream().count();

功能一樣用哪個才好呢?其實如果你的需求只是統(tǒng)計流中元素的數量的時候,二者皆可。最大的區(qū)別在于count()是一個終端操作,而counting返回的是一個收集器,其可以和其它收集器聯合使用。

查找流中的最大值和最小值

Collectors為我們提供了maxBy方法和mixBy方法,為我們提供了計算流中的最大或最小值的收集器。實例:

Comparator<Dish> dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories);
Optional<Dish> mostCalorieDish = menu.stream().collect(maxBy(dishCaloriesComparator));

匯總

求和

Collectors類專門為匯總提供了一個工廠方法: Collectors.summingInt。它可接受一個把對象映射為求和所需int的函數,并返回一個收集器;該收集器在傳遞給普通的collect方法后即執(zhí)行我們需要的匯總操作。

類Collectors.summingLong和Collectors.summingDouble方法的作用完全一樣,可以用于求和字段為long或double的情況。

求出菜單列表的總熱量的示例:

int totalCalories = menu.stream().collect(summingInt(Dish::getCalories));

上面代碼的收集過程下圖所示。在遍歷流時,會把每一道菜都映射為其熱量,然后把這個數字累加到一個累加器(這里的初始值0)。

收集器的累加過程

平均值

Collectors類的averagingInt、averagingLong 和 averagingDouble 可以為我們生成計算數值的平均數的收集器:

double avgCalories = menu.stream().collect(averagingInt(Dish::getCalories));

綜合匯總

Collectors類為我們提供了summarizingInt工廠方法,其返回的收集器可以一次性統(tǒng)計出總數、總和、平均值、最大值和最小值。

例如,通過一次summarizing操作你可以就數出菜單中元素的個數,并得到菜肴熱量總和、平均值、最大值和最小值:

IntSummaryStatistics menuStatistics =
        menu.stream().collect(summarizingInt(Dish::getCalories));

這個收集器會把所有這些信息收集到一個叫作IntSummaryStatistics的類里,它提供了方便的取值方法來訪問結果。打印menuStatisticobject會得到以下輸出:

IntSummaryStatistics{count=9, sum=4300, min=120, average=477.777778, max=800}

同樣,相應的summarizingLong和summarizingDouble工廠方法有相關的LongSummaryStatistics 和DoubleSummaryStatistics 類 型 , 適用于收集的屬性是原始類型 long 或 double 的情況。

連接字符串

Collectors類為我們提供的joining工廠方法返回的收集器會把對流中每一個對象應用toString方法得到的所有字符串連接成一個字符串。

這意味著你把菜單中所有菜肴的名稱連接起來,如下所示:

String shortMenu = menu.stream().map(Dish::getName).collect(joining());

注意: joining在內部使用了StringBuilder來把生成的字符串逐個追加起來。

此外joining工廠方法有一個重載版本可以接受元素之間的分界符,這樣你就可以得到一個逗號分隔的菜肴名稱列表:

String shortMenu = menu.stream().map(Dish::getName).collect(joining(", "));

廣義的規(guī)約匯總

前面所提及的收集器都是一個可以用reducing工廠方法定義的規(guī)約過程的特殊情況而已。Collectors.reducing工廠方法是所有這些特殊情況的一般化。

public static <T,U> Collector<T,?,U> reducing(U identity,
                    Function<? super T,? extends U> mapper, BinaryOperator<U> op)

參數解析:

  • 第一個參數時規(guī)約操作的起始值,也是流中沒有元素時的返回值。
  • 第二個參數是Function,將做一定的轉換操作。
  • 第三個參數BinaryOperator,將兩個項目累積成一個同類型的值。

我們將上面的示例轉換一下:

Comparator<Dish> dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories);
Optional<Dish> mostCalorieDish = menu.stream().collect(maxBy(dishCaloriesComparator));
// 轉換
Optional<Dish> mostCalorieDish = 
        menu.stream().collect(reducing(
                (d1,d2) -> d1.getCalories() > d1.getCalories() ? d1 : d2));

上面轉換示例中,我們使用的是一個單參數的reducing工廠方法創(chuàng)建的收集器,其可以看做是三個參數方法的特殊情況,它把流中的第一個項目作為起點,把恒等函數(即一個函數僅僅是返回其輸入參數)作為一個轉換函數。

2.2 分組

一個常見的數據庫操作是根據一個或多個屬性對集合中的項目進行分組。

假設你要把菜單中的菜按照類型進行分類,有肉的放一組,有魚的放一組,其他的都放另一組。用Collectors.groupingBy工廠方法返回的收集器就可以輕松地完成這項任務,如下所示:

Map<Dish.Type, List<Dish>> dishesByType =
        menu.stream().collect(groupingBy(Dish::getType));

這里,你給groupingBy方法傳遞了一個Function(以方法引用的形式),它提取了流中每一道Dish的Dish.Type。我們把這個Function叫作分類函數,因為它用來把流中的元素分成不同的組。如下圖所示,分組操作的結果是一個Map,把分組函數返回的值作為映射的鍵,把流中所有具有這個分類值的項目的列表作為對應的映射值。在菜單分類的例子中,鍵就是菜的類型,值就是包含所有對應類型的菜肴的列表。

分組過程

特殊應用示例:

public enum CaloricLevel{DIET,NORMAL,FAT}
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect(groupingBy(dish -> {
    if (dish.getCalories() <= 400)
        return CaloricLevel.DIET;
    else if (dish.getCalories() <= 700)
        return CaloricLevel.NORMAL;
    else
        return CaloricLevel.FAT;
}));

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 詳解mybatis 批量更新數據兩種方法效率對比

    詳解mybatis 批量更新數據兩種方法效率對比

    這篇文章主要介紹了詳解mybatis 批量更新數據兩種方法效率對比,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-02-02
  • java數據結構之搜索二叉樹

    java數據結構之搜索二叉樹

    這篇文章主要為大家詳細介紹了java數據結構之搜索二叉樹,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 如何解決java中遇到的for input string:

    如何解決java中遇到的for input string: "" 報錯問題

    在本篇文章里小編給大家整理的是一篇關于如何解決java中遇到的(for input string: "")報錯內容,需要的朋友們可以學習下。
    2020-02-02
  • Java 線程相關總結

    Java 線程相關總結

    這篇文章主要介紹了Java 線程的相關資料,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-02-02
  • springboot+vue+elementsUI實現分角色注冊登錄界面功能

    springboot+vue+elementsUI實現分角色注冊登錄界面功能

    這篇文章主要給大家介紹了關于springboot+vue+elementsUI實現分角色注冊登錄界面功能的相關資料,Spring?Boot和Vue.js是兩個非常流行的開源框架,可以用來構建Web應用程序,需要的朋友可以參考下
    2023-07-07
  • Spring?Boot中自動執(zhí)行sql腳本的方法實例

    Spring?Boot中自動執(zhí)行sql腳本的方法實例

    在SpringBoot的架構中,DataSourceInitializer類可以在項目啟動后初始化數據,我們可以通過自動執(zhí)行自定義sql腳本初始化數據,下面這篇文章主要給大家介紹了關于Spring?Boot中自動執(zhí)行sql腳本的相關資料,需要的朋友可以參考下
    2022-01-01
  • java 數據類型有哪些取值范圍多少

    java 數據類型有哪些取值范圍多少

    這篇文章主要介紹了java 數據類型有哪些取值范圍多少的相關資料,網上關于java 數據類型的資料有很多,不夠全面,這里就整理下,需要的朋友可以參考下
    2017-01-01
  • Spring?IOC容器啟動示例分析

    Spring?IOC容器啟動示例分析

    這篇文章主要給大家介紹了Spring?IOC基于注解啟動的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2023-02-02
  • Spring @Configuration注解及配置方法

    Spring @Configuration注解及配置方法

    這篇文章主要介紹了Spring @Configuration注解及配置方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java正則匹配讀取txt文件提取特定開頭和結尾的字符串

    java正則匹配讀取txt文件提取特定開頭和結尾的字符串

    通常我們可以直接通過文件流來讀取txt文件的內容,但有時候也會遇到問題,下面這篇文章主要給大家介紹了關于java正則匹配讀取txt文件提取特定開頭和結尾的字符串的相關資料,需要的朋友可以參考下
    2022-11-11

最新評論