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

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

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

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

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

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

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

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

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

首先,我們看看在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ù)列表中獲得一個stream對象,這是通過使用Liststream()方法實現(xiàn)的,下一步幾個操作 (filter, sorted, map, collect)是以鏈?zhǔn)脚帕谐梢粋€管道,形成對數(shù)據(jù)的查詢操作。

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

2、Stream起步

首先,定義一下Stream,Stream是一個來自支持聚合操作源的元素的序列。

如下特點:

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

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

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

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

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

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

3、Stream與Collection比較

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

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

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

使用集合需要開發(fā)者主動去遍歷,使用一個遍歷循環(huán),這稱為外部遍歷。

而使用一個流庫使用內(nèi)部遍歷,它自己為你遍歷元素,然后將結(jié)果保存在某處,你只要提供一個函數(shù),它就會用這個函數(shù)對元素處理完成。內(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中的類型自動轉(zhuǎn)換機制解析

    java中的類型自動轉(zhuǎn)換機制解析

    這篇文章主要介紹了java中的類型自動轉(zhuǎn)換機制,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java設(shè)計模式筆記之適配器模式

    java設(shè)計模式筆記之適配器模式

    這篇文章主要為大家詳細介紹了java設(shè)計模式之適配器模式筆記,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • java多線程編程之使用Synchronized塊同步方法

    java多線程編程之使用Synchronized塊同步方法

    synchronized塊來同步一個對象變量,也可以使用synchronized塊來同步類中的靜態(tài)方法和非靜態(tài)方法,下面使用Synchronized塊同步方法
    2014-01-01
  • Javaweb監(jiān)聽器實例之統(tǒng)計在線人數(shù)

    Javaweb監(jiān)聽器實例之統(tǒng)計在線人數(shù)

    這篇文章主要為大家詳細介紹了Javaweb監(jiān)聽器實例之統(tǒng)計在線人數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 如何在springboot項目中自定義404頁面

    如何在springboot項目中自定義404頁面

    今天點擊菜單的時候不小心點開了一個不存在的頁面,然后看到瀏覽器給的一個默認的404頁面,這篇文章主要介紹了如何在springboot項目中自定義404頁面,需要的朋友可以參考下
    2024-05-05
  • mybatis解析xml配置中${xxx}占位符的代碼邏輯

    mybatis解析xml配置中${xxx}占位符的代碼邏輯

    本文主要介紹了mybatis解析xml配置中${xxx}占位符的代碼邏輯,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2023-05-05
  • SpringBoot如何使用自定義注解實現(xiàn)接口限流

    SpringBoot如何使用自定義注解實現(xiàn)接口限流

    這篇文章主要介紹了SpringBoot如何使用自定義注解實現(xiàn)接口限流,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Springboot配置Swagger2登錄密碼的實現(xiàn)

    Springboot配置Swagger2登錄密碼的實現(xiàn)

    本文主要介紹了Springboot配置Swagger2登錄密碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • SpringBoot集成七牛云OSS的示例詳解

    SpringBoot集成七牛云OSS的示例詳解

    OSS的英文全稱是Object?Storage?Service,翻譯成中文就是對象存儲服務(wù),官方一點解釋就是對象存儲是一種使用HTTP?API存儲和檢索非結(jié)構(gòu)化數(shù)據(jù)和元數(shù)據(jù)對象的工具,本文給大家詳細介紹了SpringBoot集成七牛云OSS的示例,需要的朋友可以參考下
    2023-11-11
  • 解決SpringBoot自定義攔截器和跨域配置沖突的問題

    解決SpringBoot自定義攔截器和跨域配置沖突的問題

    這篇文章主要介紹了解決SpringBoot自定義攔截器和跨域配置沖突的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論