最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用Java8 stream處理數(shù)據(jù)

 更新時(shí)間:2021年11月04日 14:38:45   作者:banq  
這篇文章主要介紹了用Java8 stream處理數(shù)據(jù),Java 8 API的設(shè)計(jì)者重新提出了一個(gè)新的抽象稱(chēng)為流Stream,可以讓我們以一種聲明的方式處理數(shù)據(jù),此外,數(shù)據(jù)流可以充分利用多核架構(gòu)而無(wú)需編寫(xiě)多線(xiàn)程的一行代碼,下面我們一起來(lái)看看文章詳細(xì)介紹

1、stream處理數(shù)據(jù)介紹

  如果沒(méi)有集合Collection你如何處理數(shù)據(jù)?幾乎所有的Java應(yīng)用程序都要使用Collection處理數(shù)據(jù)。他們是十分重要的編程工作:例如,您可能想要?jiǎng)?chuàng)建銀行交易的集合Collection,這個(gè)集合代表客戶(hù)的狀態(tài)。然后,你可能要處理整個(gè)集合來(lái)找出的顧客花了多少錢(qián)。盡管集合如此重要,但是在Java中處理集合的技術(shù)還遠(yuǎn)遠(yuǎn)不夠完善。

首先,對(duì)集合的典型處理模式是類(lèi)似SQL操作,比如"finding"(例如,找到具有最高價(jià)的交易)或"grouping" (例如,將相關(guān)的雜物所有交易合并組) 。大多數(shù)數(shù)據(jù)庫(kù)讓您這樣的聲明方式指定的操作。例如,下面的SQL查詢(xún)可以讓您找到交易ID最高值: "SELECT id, MAX(value) from transactions" 。

正如你所看到的,我們并不需要實(shí)現(xiàn)如何具體計(jì)算最大值(例如,使用循環(huán)和一個(gè)變量來(lái)跟蹤的最高值) 。我們只能表達(dá)我們所期望的要求(獲得最大值)。只要我們顯式發(fā)出這樣的查詢(xún),數(shù)據(jù)庫(kù)就會(huì)為我們?nèi)ヌ幚???墒菫槭裁次覀儾荒茉诩?code>Collection中實(shí)現(xiàn)類(lèi)似的東西?多少次,你會(huì)發(fā)現(xiàn)自己使用循環(huán)一遍又一遍的反復(fù)遍歷集合?(如:for Object o: myLists{ ..})

其次,如何才能有效地處理真正的大數(shù)據(jù)集合?在理想的情況下,你想利用多核架構(gòu)加快處理,。然而,編寫(xiě)并行代碼很難而且容易出錯(cuò)。

Java 8 API的設(shè)計(jì)者重新提出了一個(gè)新的抽象稱(chēng)為流Stream,可以讓你以一種聲明的方式處理數(shù)據(jù)。此外,數(shù)據(jù)流可以充分利用多核架構(gòu)而無(wú)需編寫(xiě)多線(xiàn)程的一行代碼。這聽(tīng)起來(lái)不錯(cuò),不是嗎?

首先,我們看看在Java 7中,如何發(fā)現(xiàn)typegrocery 的所有交易,然后返回以交易值降序排序好的交易ID集合?

List<Transaction> groceryTransactions = new Arraylist<>();

for(Transaction t: transactions){

  if(t.getType() == Transaction.GROCERY){

    groceryTransactions.add(t);

  }

}

Collections.sort(groceryTransactions, new Comparator(){

  public int compare(Transaction t1, Transaction t2){

    return t2.getValue().compareTo(t1.getValue());

  }

});

List<Integer> transactionIds = new ArrayList<>();

for(Transaction t: groceryTransactions){

  transactionsIds.add(t.getId());

}

而在Java 8使用Stream:

List<Integer> transactionsIds =

    transactions.stream()

                .filter(t -> t.getType() == Transaction.GROCERY)

                .sorted(comparing(Transaction::getValue).reversed())

                .map(Transaction::getId)

                .collect(toList());

我們首先從交易數(shù)據(jù)列表中獲得一個(gè)stream對(duì)象,這是通過(guò)使用Liststream()方法實(shí)現(xiàn)的,下一步幾個(gè)操作 (filter, sorted, map, collect)是以鏈?zhǔn)脚帕谐梢粋€(gè)管道,形成對(duì)數(shù)據(jù)的查詢(xún)操作。

那么這段代碼如何并行操作呢?那么只要更換transactions.stream()transaction.parallelStream()即可,請(qǐng)注意lambda表達(dá)式(t-> t.getCategory() == Transaction.GROCERY)和方法引用(Transaction::getId)將在下一章詳細(xì)講解。

2、Stream起步

首先,定義一下Stream,Stream是一個(gè)來(lái)自支持聚合操作源的元素的序列。

如下特點(diǎn):

  1. 1. 所謂元素的序列,一個(gè)Stream向外提供了一個(gè)這樣的接口:特定元素類(lèi)型的值的序列,但是Stream并不實(shí)際持有也就是存儲(chǔ)這些元素,它們是在有需求時(shí)才會(huì)被計(jì)算。
  2. 2. 源:以提供Stream進(jìn)行計(jì)算消費(fèi)的源,這些源有Collection集合 Array數(shù)組或I/O資源等。
  3. 3.聚合操作:Stream支持類(lèi)似SQL操作和函數(shù)式編程的大部分操作,比如:filter, map, reduce, find, match, sorted。

此外,Stream操作不同于Collection操作有兩個(gè)根本的地方:

  • 1.管道Pipelining: 許多流Stream操作返回流Stream自身,這就允許對(duì)其操作可以像鏈條一樣排列,變成一個(gè)管道,這其中也會(huì)激活比如懶加載和short-circuiting操作。
  • 2.內(nèi)部迭代:相比于集合Collection是顯式迭代(需要我們編碼完成迭代),Stream操作是在其內(nèi)部完成迭代操作。

下面我們看看前面Stream代碼的內(nèi)部工作流程:

我們首先從交易transactions這個(gè)列表中獲得Stream對(duì)象,數(shù)據(jù)源就是交易列表,其中提供了一系列元素集合,這些元素都是供Stream操作的,下一步,我們使用了一系列對(duì)這個(gè)Stream的聚合操作,包括過(guò)濾filter (用我們指定的謂詞條件predicate過(guò)濾元素,也就是代碼t -> t.getType() == Transaction.GROCERY), 排序(用指定的比較器comparator對(duì)元素進(jìn)行排序), 以及 map (為了釋放獲取信息). 所有這些操作除了最后的collect操作,都是返回一個(gè)Stream對(duì)象,這樣就能被前后鏈接在一起變成一個(gè)長(zhǎng)的管道,可以看成是基于源數(shù)據(jù)集合的一個(gè)查詢(xún)操作。如同SQL基于數(shù)據(jù)表的有條件查詢(xún)語(yǔ)句一樣。

最后到collect被調(diào)用操作, collect操作開(kāi)始處理這個(gè)管道以返回一個(gè)結(jié)果,不再是一個(gè)結(jié)果流了,這里一個(gè)結(jié)果是List一個(gè)對(duì)象,我們看到collect接受一個(gè)recipe輸入函數(shù)然后累計(jì)Stream中元素到一個(gè)匯總結(jié)果,這里輸入函數(shù)是toList(),它是一個(gè)將將Stream轉(zhuǎn)換為L(zhǎng)ist對(duì)象。

3、Stream與Collection比較

StreamCollection集合有什么區(qū)別?Collection是關(guān)于靜止的數(shù)據(jù)結(jié)構(gòu),而Stream是有關(guān)動(dòng)詞算法和計(jì)算的。前者是主要面向內(nèi)存,存儲(chǔ)在內(nèi)存中,后者主要是面向CPU,通過(guò)CPU實(shí)現(xiàn)計(jì)算的。

舉例將一個(gè)影片存儲(chǔ)在DVD盤(pán)上,這是一個(gè)集合,因?yàn)樗麄€(gè)電影的字節(jié)數(shù)據(jù)結(jié)構(gòu),而這個(gè)影片被放在互聯(lián)網(wǎng)上,我們通過(guò)視頻軟件去觀看它時(shí),它實(shí)際是被流化了,它變成了一個(gè)字節(jié)流,流是與時(shí)間有關(guān)的概念,而數(shù)據(jù)結(jié)構(gòu)是與時(shí)間無(wú)關(guān),不會(huì)隨著時(shí)間變化變化,流正好相反,隨著時(shí)間不斷地動(dòng)態(tài)變化,如同水流一樣潺潺不斷。

所以,集合與流的主要區(qū)別是是否需要被計(jì)算,集合是一個(gè)內(nèi)存數(shù)據(jù)結(jié)構(gòu),集合中每個(gè)元素在加入到集合之前已經(jīng)被計(jì)算了,相反,流是在即時(shí)要求即時(shí)計(jì)算。

使用集合需要開(kāi)發(fā)者主動(dòng)去遍歷,使用一個(gè)遍歷循環(huán),這稱(chēng)為外部遍歷。

而使用一個(gè)流庫(kù)使用內(nèi)部遍歷,它自己為你遍歷元素,然后將結(jié)果保存在某處,你只要提供一個(gè)函數(shù),它就會(huì)用這個(gè)函數(shù)對(duì)元素處理完成。內(nèi)外遍歷的區(qū)別如下代碼:

List<String> transactionIds = new ArrayList<>();

for(Transaction t: transactions){

    transactionIds.add(t.getId()); //外部遍歷

}

 

List<Integer> transactionIds =

    transactions.stream()

                .map(Transaction::getId) //內(nèi)部遍歷

                .collect(toList());

到此這篇關(guān)于用Java8 stream處理數(shù)據(jù)的文章就介紹到這了,更多相關(guān) stream處理數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring maven filtering使用方法詳解

    Spring maven filtering使用方法詳解

    這篇文章主要介紹了Spring maven filtering使用方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 使用Jenkins Pipeline自動(dòng)化構(gòu)建發(fā)布Java項(xiàng)目的方法

    使用Jenkins Pipeline自動(dòng)化構(gòu)建發(fā)布Java項(xiàng)目的方法

    這篇文章主要介紹了使用Jenkins Pipeline自動(dòng)化構(gòu)建發(fā)布Java項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • Spring P標(biāo)簽的使用詳解

    Spring P標(biāo)簽的使用詳解

    這篇文章主要介紹了Spring P標(biāo)簽的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • spring boot啟動(dòng)后直接關(guān)閉了的問(wèn)題解決

    spring boot啟動(dòng)后直接關(guān)閉了的問(wèn)題解決

    本文主要介紹了spring boot啟動(dòng)后直接關(guān)閉了的問(wèn)題解決,SpringBoot項(xiàng)目啟動(dòng)后自動(dòng)關(guān)閉的原因是未引入web依賴(lài),導(dǎo)致以普通Java項(xiàng)目運(yùn)行,下面就來(lái)介紹一下解決方法,感興趣的可以了解一下
    2025-02-02
  • Java進(jìn)階核心之InputStream流深入講解

    Java進(jìn)階核心之InputStream流深入講解

    這篇文章主要給大家介紹了關(guān)于Java進(jìn)階核心之InputStream流的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Java使用String類(lèi)格式化當(dāng)前日期實(shí)現(xiàn)代碼

    Java使用String類(lèi)格式化當(dāng)前日期實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java使用String類(lèi)格式化當(dāng)前日期實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2014-02-02
  • 圖解Java經(jīng)典算法快速排序的原理與實(shí)現(xiàn)

    圖解Java經(jīng)典算法快速排序的原理與實(shí)現(xiàn)

    快速排序是基于二分的思想,對(duì)冒泡排序的一種改進(jìn)。主要思想是確立一個(gè)基數(shù),將小于基數(shù)的數(shù)放到基數(shù)左邊,大于基數(shù)的數(shù)字放到基數(shù)的右邊,然后在對(duì)這兩部分進(jìn)一步排序,從而實(shí)現(xiàn)對(duì)數(shù)組的排序
    2022-09-09
  • druid連接池的參數(shù)配置示例全面解析

    druid連接池的參數(shù)配置示例全面解析

    這篇文章主要為大家介紹了druid連接池的參數(shù)配置示例全面解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java基于Google zxing生成帶logo的二維碼圖片

    Java基于Google zxing生成帶logo的二維碼圖片

    zxing是一個(gè)開(kāi)放源碼的,用java實(shí)現(xiàn)的多種格式的1D/2D條碼圖像處理庫(kù),本文主要介紹了Java基于Google zxing生成帶logo的二維碼圖片,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 基于SpringBoot和PostGIS的某國(guó)基地可視化實(shí)戰(zhàn)

    基于SpringBoot和PostGIS的某國(guó)基地可視化實(shí)戰(zhàn)

    本文以Java開(kāi)發(fā)語(yǔ)言為例,使用SpringBoot框架來(lái)進(jìn)行后臺(tái)開(kāi)發(fā),詳細(xì)講解如何使用Leaflet對(duì)PostGIS的全球基地信息進(jìn)行Web可視化,最后分享Web可視化結(jié)果,感興趣的朋友跟隨小編一起看看吧
    2024-08-08

最新評(píng)論

谷城县| 章丘市| 通榆县| 洛隆县| 财经| 太谷县| 通山县| 始兴县| 巩留县| 综艺| 榆中县| 宁远县| 喜德县| 花垣县| 登封市| 曲阜市| 绥滨县| 云林县| 元阳县| 洛隆县| 涞源县| 视频| 炎陵县| 广宗县| 桑日县| 扶余县| 方城县| 昌吉市| 凤城市| 长沙县| 通许县| 沅陵县| 云南省| 宁化县| 芦溪县| 洛宁县| 都江堰市| 漯河市| 东安县| 苍梧县| 福州市|