使用Java8?Stream流的skip?+?limit實(shí)現(xiàn)批處理的方法
為什么需要 Stream
Stream 作為 Java 8 的一大亮點(diǎn),它與 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 對 XML 解析的 Stream,也不是 Amazon Kinesis 對大數(shù)據(jù)實(shí)時處理的 Stream。Java 8 中的 Stream 是對集合(Collection)對象功能的增強(qiáng),它專注于對集合對象進(jìn)行各種非常便利、高效的聚合操作(aggregate operation),或者大批量數(shù)據(jù)操作 (bulk data operation)。Stream API 借助于同樣新出現(xiàn)的 Lambda 表達(dá)式,極大的提高編程效率和程序可讀性。同時它提供串行和并行兩種模式進(jìn)行匯聚操作,并發(fā)模式能夠充分利用多核處理器的優(yōu)勢,使用 fork/join 并行方式來拆分任務(wù)和加速處理過程。通常編寫并行代碼很難而且容易出錯, 但使用 Stream API 無需編寫一行多線程的代碼,就可以很方便地寫出高性能的并發(fā)程序。所以說,Java 8 中首次出現(xiàn)的 java.util.stream 是一個函數(shù)式語言+多核時代綜合影響的產(chǎn)物。
什么是流
Stream不是集合元素,它不是數(shù)據(jù)結(jié)構(gòu)并不保存數(shù)據(jù),它是有關(guān)算法和計算的,它更像一個高級版本的 Iterator。原始版本的 Iterator,用戶只能顯式地一個一個遍歷元素并對其執(zhí)行某些操作;高級版本的 Stream,用戶只要給出需要對其包含的元素執(zhí)行什么操作,比如 “過濾掉長度大于 10 的字符串”、“獲取每個字符串的首字母”等,Stream 會隱式地在內(nèi)部進(jìn)行遍歷,做出相應(yīng)的數(shù)據(jù)轉(zhuǎn)換。Stream 就如同一個迭代器(Iterator),單向,不可往復(fù),數(shù)據(jù)只能遍歷一次,遍歷過一次后即用盡了,就好比流水從面前流過,一去不復(fù)返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顧名思義,當(dāng)使用串行方式去遍歷時,每個 item 讀完后再讀下一個 item。而使用并行去遍歷時,數(shù)據(jù)會被分成多個段,其中每一個都在不同的線程中處理,然后將結(jié)果一起輸出。Stream 的并行操作依賴于 Java7 中引入的 Fork/Join 框架(JSR166y)來拆分任務(wù)和加速處理過程。Java 的并行 API 演變歷程基本如下:
- 1.0-1.4 中的 java.lang.Thread
- 5.0 中的 java.util.concurrent
- 6.0 中的 Phasers 等
- 7.0 中的 Fork/Join 框架
- 8.0 中的 Lambda
Stream 的另外一大特點(diǎn)是,數(shù)據(jù)源本身可以是無限的。
1、一般進(jìn)行批處理時會將數(shù)據(jù)加入到一個臨時的集合中,當(dāng)數(shù)據(jù)量達(dá)到一定大小后進(jìn)行下一步操作,數(shù)據(jù)量不足時需要進(jìn)行額外的判斷;
2、若使用Java8的Stream流中的 skip + limit 則可以讓我們對集合方便快捷的操作,其中:
(1)skip(x):返回丟棄流中的前x個元素后剩下元素組成的新流;若原流中包含的元素個數(shù)小于x,則返回空流。
(2)limit(x): 對一個Stream流進(jìn)行截斷操作,獲取其前x個元素;若原流中包含的元素個數(shù)小于x,那就獲取其所有的元素;
3、實(shí)例代碼如下:
public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 10; i < 36; i++) { list.add(i); } int limit = 10; for (int offset = 0; offset < list.size(); offset += limit) { List<Integer> subList = list.stream() .skip(offset) .limit(limit) .collect(Collectors.toList()); System.out.println(subList); } }
輸出結(jié)果:
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
[30, 31, 32, 33, 34, 35]
3、通過結(jié)果也可以看出 skip 配合 limit 操作使用時, limit 是最多取出限制的大小,不用再判斷最后一批數(shù)據(jù)量大小不夠限定的大小時的處理。
改進(jìn)版
int j = 0, size = list.size(), batchSize = 100; while (j < size) { batchList = list.stream().skip(j).limit(Math.min(j + batchSize, size) - j).collect(Collectors.toList()); j += batchSize; }
到此這篇關(guān)于使用Java8 Stream流的skip + limit實(shí)現(xiàn)批處理的文章就介紹到這了,更多相關(guān)Java8 Stream流批處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java FileDescriptor總結(jié)_動力節(jié)點(diǎn)Java學(xué)院整理
FileDescriptor 是“文件描述符”??梢员挥脕肀硎鹃_放文件、開放套接字等。接下來通過本文給大家分享Java FileDescriptor總結(jié),感興趣的朋友一起學(xué)習(xí)吧2017-05-05java獲取百度網(wǎng)盤真實(shí)下載鏈接的方法
這篇文章主要介紹了java獲取百度網(wǎng)盤真實(shí)下載鏈接的方法,涉及java針對URL操作及頁面分析的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07使用SpringBoot配置多數(shù)據(jù)源的經(jīng)驗(yàn)分享
這篇文章主要介紹了使用SpringBoot配置多數(shù)據(jù)源的經(jīng)驗(yàn)分享,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04Mybatis之映射實(shí)體類中不區(qū)分大小寫的解決
這篇文章主要介紹了Mybatis之映射實(shí)體類中不區(qū)分大小寫的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11java天數(shù)計算函數(shù)(當(dāng)前月天數(shù)、某月總天數(shù)及某月剩余天數(shù))4種方法實(shí)現(xiàn)代碼
日常開發(fā)中會遇到關(guān)于日期的計算,比如當(dāng)月的天數(shù)、兩日期之間的天數(shù)、當(dāng)月剩余天數(shù)等等,這篇文章主要給大家介紹了關(guān)于java天數(shù)計算函數(shù)(當(dāng)前月天數(shù)、某月總天數(shù)及某月剩余天數(shù))4種方法實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2023-10-10JavaWeb項(xiàng)目中springmvc和tomcat對靜態(tài)文件的處理
這篇文章主要介紹了JavaWeb項(xiàng)目中springmvc和tomcat對靜態(tài)文件的處理 的相關(guān)資料,需要的朋友可以參考下2016-07-07- 在Java中,生成隨機(jī)數(shù)有兩種方法。1是使用Random類。2是使用Math類中的random方法??聪旅娴睦邮褂冒?/div> 2013-11-11
最新評論