国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用 Java 流進(jìn)行分組和聚合,高效處理大量數(shù)據(jù)不再是夢!

這篇具有很好參考價值的文章主要介紹了使用 Java 流進(jìn)行分組和聚合,高效處理大量數(shù)據(jù)不再是夢!。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

了解使用 Java Streams 解決問題的直接途徑,Java Streams 是一個允許我們快速有效地處理大量數(shù)據(jù)的框架。

當(dāng)我們對列表中的元素進(jìn)行分組時,我們可以隨后聚合分組元素的字段以執(zhí)行有意義的操作,幫助我們分析數(shù)據(jù)。一些示例是加法、平均值或最大值/最小值。這些單個字段的聚合可以使用 Java Streams 和 Collectors 輕松完成。該文檔提供了如何進(jìn)行這些類型計算的簡單示例。

但是,還有更復(fù)雜的聚合,例如加權(quán)平均值、幾何平均值。此外,可能需要同時聚合多個字段。在本文中,我們將展示使用 Java Streams 解決此類問題的直接途徑。使用這個框架使我們能夠快速有效地處理大量數(shù)據(jù)。

我們假設(shè)讀者對Java Streams和實用程序Collectors類有基本的了解。

問題布局

讓我們考慮一個簡單的例子來展示我們想要解決的問題類型。我們將使它非常通用,以便我們可以輕松地概括它。讓我們考慮TaxEntry由以下代碼定義的實體列表:

public class TaxEntry {

    private String state;
    private String city;
    private int numEntries;
    private double price;
    //Constructors, getters, hashCode, equals etc
}

計算給定城市的條目總數(shù)非常簡單:

Map<String, Integer> totalNumEntriesByCity = 
              taxes.stream().collect(Collectors.groupingBy(TaxEntry::getCity, 
                                                           Collectors.summingInt(TaxEntry::getNumEntries)));

Collectors.summingInt(TaxEntry::getNumEntries)));

Collectors.groupingBy接受兩個參數(shù):一個分類器函數(shù)進(jìn)行分組,一個收集器對屬于給定組的所有元素進(jìn)行下游聚合。我們TaxEntry::getCity用作分類器函數(shù)。對于下游,我們使用Collectors::summingIntwhich 返回一個Collector總和我們?yōu)槊總€分組元素獲得的稅收條目的數(shù)量。

如果我們嘗試找到復(fù)合分組,事情會稍微復(fù)雜一些。例如,對于前面的示例,給定州和?城市的條目總數(shù)。有幾種方法可以做到這一點,但一個非常簡單的方法是首先定義:

record StateCityGroup(String state, String city) {}

請注意,我們使用的是 Javarecord,這是一種定義不可變類的簡潔方法。此外,Java 編譯器為我們生成字段訪問器方法hashCode、、等號和toString實現(xiàn)。有了這個,現(xiàn)在的解決方案很簡單:

Map<StateCityGroup, Integer> totalNumEntriesForStateCity = 
                    taxes.stream().collect(groupingBy(p -> new StateCityGroup(p.getState(), p.getCity()), 
                                                      Collectors.summingInt(TaxEntrySimple::getNumEntries))
                                          );

因為Collectors::groupingBy我們使用 lambda 表達(dá)式設(shè)置分類器函數(shù),該表達(dá)式創(chuàng)建一個StateCityGroup封裝每個州-城市的新記錄。下游 Collector 和之前一樣。

注意:為了簡潔起見,在代碼示例中,我們將假設(shè) Collectors 類的所有方法都是靜態(tài)導(dǎo)入的,因此我們不必顯示它們的類限定。

如果我們想同時進(jìn)行多個聚合,事情開始變得更加復(fù)雜。例如,查找給定州和城市的條目數(shù)和平均價格之和。該庫沒有為這個問題提供簡單的解決方案。

為了開始解決這個問題,我們從之前的聚合中獲取線索,并定義一個記錄來封裝所有需要聚合的字段:

record TaxEntryAggregation (int totalNumEntries, double averagePrice ) {}

現(xiàn)在,我們?nèi)绾瓮瑫r對兩個字段進(jìn)行聚合?正如以下代碼中所建議的那樣,總是有可能進(jìn)行兩次流收集以分別查找每個聚合:

Map<StateCityGroup, TaxEntryAggregation> aggregationByStateCity = taxes.stream().collect(
           groupingBy(p -> new StateCityGroup(p.getState(), p.getCity()),
                      collectingAndThen(Collectors.toList(), 
                                        list -> {int entries = list.stream().collect(
                                                                   summingInt(TaxEntrySimple::getNumEntries));
                                                 double priceAverage = list.stream().collect(
                                                                   averagingDouble(TaxEntrySimple::getPrice));
                                                 return new TaxEntryAggregation(entries, priceAverage);})));

分組像以前一樣完成,但對于下游,我們使用Collectors::collectingAndThen(第 3 行)進(jìn)行聚合。這個函數(shù)有兩個參數(shù):

  • 我們轉(zhuǎn)換為列表的初始分組的下載流(Collectors::toList()在第 3 行中使用)
  • Finisher 函數(shù)(第 4-9 行),我們使用 lambda 表達(dá)式從前一個列表中創(chuàng)建兩個不同的流來進(jìn)行聚合并將它們組合在一個新TaxEntryAggregation記錄 中返回

想象一下,我們想同時進(jìn)行更多的字段聚合。我們需要相應(yīng)地增加下游列表中的流數(shù)量。代碼變得效率低下、重復(fù)性非常高且不太理想。我們應(yīng)該尋找更好的替代品。

此外,問題還不止于此,一般來說,我們受限于可以使用 Collectors 輔助類進(jìn)行的聚合類型。他們的方法 summing*、averaging* 和 summarizing* 僅支持整數(shù)、長整數(shù)和雙精度本機(jī)類型。如果我們有更復(fù)雜的類型,比如BigIntegeror ,我們該怎么辦BigDecimal?

雪上加霜的是,summarizing* 方法僅提供 min、max、count、sum 和 average 的匯總統(tǒng)計數(shù)據(jù)。如果我們想要執(zhí)行更復(fù)雜的計算,例如加權(quán)平均值或幾何平均值怎么辦?

有些人會爭辯說我們總是可以編寫自定義收集器,但這需要了解收集器接口并很好地理解流收集器流程。使用 Collectors 類中的實用方法提供的內(nèi)置收集器更直接。在下一節(jié)中,我們將展示一些關(guān)于如何實現(xiàn)此目的的策略。

復(fù)雜的多重聚合:解決路徑

讓我們考慮一個簡單的例子,它將突出我們在上一節(jié)中提到的挑戰(zhàn)。假設(shè)我們有以下實體:

public class TaxEntry {
    private String state;
    private String city;
    private BigDecimal rate;
    private BigDecimal price;
    record StateCityGroup(String state, String city) {
    }
    //Constructors, getters, hashCode/equals etc
}

我們首先詢問每個不同的州-城市對如何找到條目的總數(shù)以及rateprice(∑(rate * price)) 的乘積的總和。請注意,我們正在使用BigDecimal.

正如我們在上一節(jié)中所做的那樣,我們定義了一個封裝聚合的類:

record RatePriceAggregation(int count, BigDecimal ratePrice) {}

起初可能看起來令人驚訝,但是對于后面跟著簡單聚合的分組的直接解決方案是使用Collectors::toMap.讓我們看看我們將如何做到這一點:

Map<StateCityGroup, RatePriceAggregation> mapAggregation = taxes.stream().collect(
      toMap(p -> new StateCityGroup(p.getState(), p.getCity()), 
            p -> new RatePriceAggregation(1, p.getRate().multiply(p.getPrice())), 
            (u1,u2) -> new RatePriceAggregation( u1.count() + u2.count(), u1.ratePrice().add(u2.ratePrice()))
            ));

(第Collectors::toMap2 行)接受三個參數(shù),我們執(zhí)行以下實現(xiàn):

  • 第一個參數(shù)是一個 lambda 表達(dá)式,用于生成地圖的鍵。此函數(shù)創(chuàng)建StateCityGroup為地圖的鍵。這將按州和城市對元素進(jìn)行分組(第 2 行)。
  • 第二個參數(shù)產(chǎn)生地圖的值。在我們的例子中,我們創(chuàng)建了RatePriceAggregation一個計數(shù)為 1 以及 rate 和 price 的乘積的初始化(第 3 行)。
  • 最后,最后一個參數(shù)是BinaryOperator用于合并多個元素映射到同一個州-城市鍵的情況。我們將計數(shù)和價格相加以進(jìn)行匯總(第 4 行)。

讓我們演示如何設(shè)置一些示例數(shù)據(jù):

List<TaxEntry> taxes = Arrays.asList(
                          new TaxEntry("New York", "NYC", BigDecimal.valueOf(0.2), BigDecimal.valueOf(20.0)), 
                          new TaxEntry("New York", "NYC", BigDecimal.valueOf(0.4), BigDecimal.valueOf(10.0)), 
                          new TaxEntry("New York", "NYC", BigDecimal.valueOf(0.6), BigDecimal.valueOf(10.0)), 
                          new TaxEntry("Florida", "Orlando", BigDecimal.valueOf(0.3), BigDecimal.valueOf(13.0)));

從前面的代碼示例中獲取紐約的結(jié)果很簡單:

System.out.println("New York: " + mapAggregation.get(new StateCityGroup("New York", "NYC")));

這打?。?/p>

New York: RatePriceAggregation[count=3, ratePrice=14.00]

這是一個直接的實現(xiàn),它決定了多個字段和非原始數(shù)據(jù)類型(BigDecimal在我們的例子中)的分組和聚合。但是,它的缺點是它沒有任何終結(jié)器允許您執(zhí)行額外的操作。例如,你不能做任何類型的平均值。

為了展示這個問題,讓我們考慮一個更復(fù)雜的問題。假設(shè)我們想要找到費率-價格的加權(quán)平均值,以及每個州和城市對的所有價格的總和。特別是,要找到加權(quán)平均值,我們需要計算屬于每個州-城市對的所有條目的費率和價格的乘積之和,然后除以每個案例的條目總數(shù) n: 1/n ∑(費率 * 價格)。

為了解決這個問題,我們開始定義一個包含聚合的記錄:

record TaxEntryAggregation(int count, BigDecimal weightedAveragePrice, BigDecimal totalPrice) {}

有了這個,我們可以進(jìn)行以下實現(xiàn):

Map<StateCityGroup, TaxEntryAggregation> groupByAggregation = taxes.stream().collect(
    groupingBy(p -> new StateCityGroup(p.getState(), p.getCity()), 
               mapping(p -> new TaxEntryAggregation(1, p.getRate().multiply(p.getPrice()), p.getPrice()), 
                       collectingAndThen(reducing(new TaxEntryAggregation(0, BigDecimal.ZERO, BigDecimal.ZERO),
                                                  (u1,u2) -> new TaxEntryAggregation(u1.count() + u2.count(),
                                                      u1.weightedAveragePrice().add(u2.weightedAveragePrice()), 
                                                      u1.totalPrice().add(u2.totalPrice()))
                                                  ),
                                         u -> new TaxEntryAggregation(u.count(), 
                                                 u.weightedAveragePrice().divide(BigDecimal.valueOf(u.count()),
                                                                                 2, RoundingMode.HALF_DOWN), 
                                                 u.totalPrice())
                                         )
                      )
              ));

我們可以看到代碼稍微復(fù)雜一些,但可以讓我們得到我們正在尋找的解決方案。我們將更詳細(xì)地關(guān)注它:

  • Collectors::groupingBy(第 2 行):
  1. 對于分類功能,我們創(chuàng)建一個StateCityGroup?記錄
  2. 對于下游,我們調(diào)用Collectors::mapping(第 3 行):
  • 對于第一個參數(shù),我們應(yīng)用于輸入元素的映射器將分組的州-城市稅收記錄轉(zhuǎn)換為TaxEntryAggregation將初始計數(shù)分配為 1 的新條目,將稅率乘以價格,然后設(shè)置價格(第 3 行)。
  • 對于下游,我們調(diào)用Collectors::collectingAndThen(第 4 行),正如我們將看到的,這將允許我們對下游收集器應(yīng)用一個完成轉(zhuǎn)換。
    • 調(diào)用Collectors::reducing(第 4 行)
  1. 創(chuàng)建一個默認(rèn)值TaxEntryAggregation?以涵蓋沒有下游元素的情況(第 4 行)。
  2. Lambda 表達(dá)式進(jìn)行歸約并返回一個TaxEntryAggregation包含字段聚合的新表達(dá)式(第 5、6 7 行)
  • 使用在先前歸約中計算的計數(shù)執(zhí)行完成轉(zhuǎn)換,計算平均值并返回最終結(jié)果TaxEntryAggregation(第 9、10、11 行)。

我們看到這種實現(xiàn)不僅允許我們同時進(jìn)行多個字段聚合,而且還可以在多個階段執(zhí)行復(fù)雜的計算。

這可以很容易地推廣到解決更復(fù)雜的問題。路徑很簡單:定義一條記錄,封裝所有需要聚合的字段,Collectors::mapping用來初始化記錄,然后申請Collectors::collectingAndThen做歸約和最終聚合。

和以前一樣,我們可以獲得紐約的聚合:

System.out.println("Finished aggregation: " + groupByAggregation.get(new StateCityGroup("New York", "NYC")));

我們得到結(jié)果:

Finished aggregation: TaxEntryAggregation[count=3, weightedAveragePrice=4.67, totalPrice=40.0]

還值得指出的是,由于TaxEntryAggregation是 Java?record,它是不可變的,因此可以使用流收集器庫提供的??支持來并行計算。

結(jié)論

我們已經(jīng)展示了幾種策略來使用聚合進(jìn)行復(fù)雜的多字段分組,這些聚合包括具有多字段和跨字段計算的非原始數(shù)據(jù)類型。這是一個使用 Java 流和 Collectors API 的記錄列表,因此它為我們提供了快速有效地處理大量數(shù)據(jù)的能力。文章來源地址http://www.zghlxwxcb.cn/news/detail-732724.html

到了這里,關(guān)于使用 Java 流進(jìn)行分組和聚合,高效處理大量數(shù)據(jù)不再是夢!的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Java Elasticsearch多條件分組聚合查詢

    需求 ????????在項目開發(fā)中,需要從elasticsearch中查詢?nèi)罩緮?shù)據(jù),先統(tǒng)計每一天的日志調(diào)用量,然后在每一天的分組聚合基礎(chǔ)上,再分組聚合統(tǒng)計成功和失敗的日志調(diào)用量。 代碼

    2024年02月08日
    瀏覽(27)
  • 使用Elasticsearch處理大量數(shù)據(jù),如何翻頁查詢

    當(dāng)使用Elasticsearch處理大量數(shù)據(jù)時,從第一頁直接跳轉(zhuǎn)到第100頁進(jìn)行查詢確實是一個挑戰(zhàn),因為需要計算跳過的記錄數(shù)并有效地獲取目標(biāo)頁的數(shù)據(jù)。以下是一些建議來實現(xiàn)這種跳頁查詢: 使用 from 和 size 參數(shù) : Elasticsearch提供了 from 和 size 參數(shù)來實現(xiàn)分頁。 from 參數(shù)指定了要

    2024年04月15日
    瀏覽(22)
  • group by聚合分組后如何獲取分組數(shù)據(jù)

    group by聚合分組后如何獲取分組數(shù)據(jù)

    之前用group by分組后一直困惑怎么把分組后的數(shù)據(jù)拿到,因為分組后同一組的只有一條數(shù)據(jù),最后發(fā)現(xiàn)了 group_concat函數(shù)。記錄一下,以后能用。 語法:group_concat( [distinct] 要連接的字段 [order by 排序字段 asc/desc ] [separator \\\'分隔符\\\'] ) 說明:通過使用 distinct 可以排除重復(fù)值(去重

    2024年02月05日
    瀏覽(24)
  • 數(shù)據(jù)分析 — Pandas 分組聚合

    pandas.apply() 是 Pandas 庫中的一個函數(shù),用于在 DataFrame 或 Series 上應(yīng)用自定義函數(shù)。這個函數(shù)可以 沿著指定的軸(行或列)逐行或逐列地應(yīng)用函數(shù) ,從而實現(xiàn)對數(shù)據(jù)的定制化操作。 參數(shù): func(必需):這是要應(yīng)用的函數(shù),可以是一個 Python 函數(shù)、lambda 函數(shù)或可調(diào)用對象。這

    2024年02月19日
    瀏覽(18)
  • Java 8 Stream實用篇,玩轉(zhuǎn)集合的篩選、歸約、分組、聚合

    Java 8 Stream實用篇,玩轉(zhuǎn)集合的篩選、歸約、分組、聚合

    Stream將要處理的元素集合看作一種流,在流的過程中,借助Stream API對流中的元素進(jìn)行操作,比如:篩選、排序、聚合等。 Stream可以由數(shù)組或集合創(chuàng)建,對流的操作分為兩種: 中間操作 ,每次返回一個新的流,可以有多個。 終端操作 ,每個流只能進(jìn)行一次終端操作,終端操

    2024年01月20日
    瀏覽(29)
  • 如何使用Puppeteer進(jìn)行新聞網(wǎng)站數(shù)據(jù)抓取和聚合

    如何使用Puppeteer進(jìn)行新聞網(wǎng)站數(shù)據(jù)抓取和聚合

    Puppeteer是一個基于Node.js的庫,它提供了一個高級的API來控制Chrome或Chromium瀏覽器。通過Puppeteer,我們可以實現(xiàn)各種自動化任務(wù),如網(wǎng)頁截圖、PDF生成、表單填寫、網(wǎng)絡(luò)監(jiān)控等。本文將介紹如何使用Puppeteer進(jìn)行新聞網(wǎng)站數(shù)據(jù)抓取和聚合,以網(wǎng)易新聞和杭州亞運會為例。 數(shù)據(jù)抓取

    2024年02月10日
    瀏覽(22)
  • 分組聚合不再難:Pandas groupby使用指南

    分組聚合不再難:Pandas groupby使用指南

    處理大量數(shù)據(jù)時,經(jīng)常需要對數(shù)據(jù)進(jìn)行分組和匯總, groupby 為我們提供了一種簡潔、高效的方式來實現(xiàn)這些操作,從而簡化了數(shù)據(jù)分析的流程。 分組 是指根據(jù)一個或多個列的值將數(shù)據(jù)分成多個組,每個組包含具有相同鍵值(這里的鍵值即用來分組的列值)的數(shù)據(jù)行。 聚合

    2024年03月09日
    瀏覽(26)
  • 【算法】在vue3的ts代碼中分組group聚合源數(shù)據(jù)列表

    有一個IListany()對象列表, 示例數(shù)據(jù)為[{id:\\\'1\\\',fieldName:\\\'field1\\\',value:\\\'1\\\'},{id:\\\'1\\\',fieldName:\\\'field2\\\',value:\\\'2\\\'},{id:\\\'2\\\',fieldName:\\\'field1\\\',value:\\\'1\\\'},{id:\\\'2\\\',fieldName:\\\'field2\\\',value:\\\'2\\\'}] 那么在ts中將它們根據(jù)id分組構(gòu)建為兩個dynamicObject,類推,如果id有n個,那需要自動構(gòu)建n個dynamicObject。 算法實現(xiàn): 在以

    2024年02月11日
    瀏覽(29)
  • 使用java8 新特性stream流對List<Map<String, Object>>集合進(jìn)行遍歷、過濾、查詢、去重、排序、分組

    對于一個ListMapString, Object類型的數(shù)據(jù),可以使用Java 8的新特性stream流來進(jìn)行遍歷、過濾、查詢、去重、排序、分組等操作。 遍歷: 過濾: 查詢: 去重: 排序: 分組:

    2024年02月10日
    瀏覽(106)
  • 【數(shù)據(jù)庫】通過實例講清楚,Mongodb的增刪查改,分組查詢,聚合查詢aggregate

    【數(shù)據(jù)庫】通過實例講清楚,Mongodb的增刪查改,分組查詢,聚合查詢aggregate

    目錄 一.基礎(chǔ)概念 二.數(shù)據(jù)庫的管理 1.創(chuàng)建數(shù)據(jù)庫 2.刪除數(shù)據(jù)庫 二.集合的管理 1.顯示所有集合 2.創(chuàng)建集合 3.刪除當(dāng)前集合 4.向集合中插入元素 三.文檔的管理 1.文檔插入 2.文檔的更新 3.文檔的刪除 4.文檔查詢 (1)查詢基本語法: (2)查詢table2集合下的所有文檔 (3)查詢t

    2024年02月10日
    瀏覽(13)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包