日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

高效遍历Java容器

發(fā)布時(shí)間:2025/3/21 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高效遍历Java容器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

通過(guò)本文,你可以更深入的學(xué)習(xí) Java 語(yǔ)言中 forEach 語(yǔ)法的知識(shí),以及它和 C 語(yǔ)言形式的 for 循環(huán)、 Steam API 的對(duì)比。

?

簡(jiǎn)介


Java 程序員經(jīng)常使用容器,比如 ArrayList 和 HashSet。Java 8 中的 lambda 語(yǔ)法和 steaming API 可以讓我們更方便的使用容器。大部分情況下,我們僅僅處理幾千個(gè)元素,也不會(huì)去考慮性能問(wèn)題。但是,在一些極端場(chǎng)景下,如果我們需要遍歷上百萬(wàn)個(gè)元素,性能問(wèn)題就凸顯出來(lái)了。

本文將采用 JMH 計(jì)算每塊代碼的運(yùn)行時(shí)間。

?

forEach vs. C Style vs. Stream API


遍歷是一個(gè)基本的功能。所有編程語(yǔ)言都提供了簡(jiǎn)單的語(yǔ)法,讓程序員去遍歷容器。

Steam API 以一種非常直接的形式來(lái)遍歷容器。

public?List<Integer> streamSingleThread(BenchMarkState state){List<Integer> result =?new?ArrayList<>(state.testData.size());state.testData.stream().forEach(item -> {result.add(item);});return?result; } public?List<Integer> streamMultiThread(BenchMarkState state){List<Integer> result =?new?ArrayList<>(state.testData.size());state.testData.stream().parallel().forEach(item -> {result.add(item);});return?result; }

?

forEach 循環(huán)也很簡(jiǎn)單:

public?List<Integer>?forEach(BenchMarkState state){List<Integer> result =?new?ArrayList<>(state.testData.size());for(Integer item : state.testData){result.add(item);}return?result; }

?

C 語(yǔ)言形式的 for 循環(huán)啰嗦一些,不過(guò)依然很緊湊:

public?List<Integer>?forCStyle(BenchMarkState state){int?size = state.testData.size();List<Integer> result =?new?ArrayList<>(size);for(int?j =?0; j < size; j ++){result.add(state.testData.get(j));}return?result; }

?

以下是性能報(bào)告:

Benchmark ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Mode ?Cnt ? Score ? Error ?Units TestLoopPerformance.forCStyle ? ? ? ? ? avgt ?200??18.068?±?0.074??ms/op TestLoopPerformance.forEach?? ? ? ? ? ? avgt ?200??30.566?±?0.165??ms/op TestLoopPerformance.streamMultiThread ? avgt ?200??79.433?±?0.747??ms/op TestLoopPerformance.streamSingleThread ?avgt ?200??37.779?±?0.485??ms/op

?

使用 C 語(yǔ)言形式的 for 循環(huán),JVM 每次僅僅增加一個(gè)數(shù)字,然后直接從內(nèi)存里讀出數(shù)據(jù)。這使得它非常迅速。但是 forEach 就大不一樣,根據(jù) StackOverFlow 的這篇回答(https://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work/85206#85206),和 Oracle 的文章(https://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html),JVM 需要把 forEach 轉(zhuǎn)換成一個(gè) iterator,然后每個(gè)元素都調(diào)用一次 hasNext() 方法。這就是 forEach 比 C 語(yǔ)言的形式慢一些的原因。

?

哪一個(gè)是遍歷 Set 最高效的方法呢?


我們先定義測(cè)試數(shù)據(jù)集:

@State(Scope.Benchmark) public?static?class?BenchMarkState?{public?Set<Integer> testData =?new?HashSet<>(500000);@Setup(Level.Trial)public?void?doSetup()?{for(int?i =?0; i <?500000; i++){testData.add(Integer.valueOf(i));}}@TearDown(Level.Trial)public?void?doTearDown()?{testData =?new?HashSet<>(500000);}}

?

Java 中的 Set 也支持 Steam API 和 forEach 循環(huán)。參考之前的測(cè)試,如果我們把 Set 轉(zhuǎn)換成 ArrayList,然后遍歷 ArrayList,或許性能會(huì)好一些?

public?List<Integer>?forCStyle(BenchMarkState state){int?size = state.testData.size();List<Integer> result =?new?ArrayList<>(size);Integer[] temp = (Integer[]) state.testData.toArray(new?Integer[size]);for(int?j =?0; j < size; j ++){result.add(temp[j]);}return?result; }

?

如果把 iterator 和 C 語(yǔ)言形式結(jié)合起來(lái)呢?

public?List<Integer>?forCStyleWithIteration(BenchMarkState state){int?size = state.testData.size();List<Integer> result =?new?ArrayList<>(size);Iterator<Integer> iteration = state.testData.iterator();for(int?j =?0; j < size; j ++){result.add(iteration.next());}return?result;}

?

或者,簡(jiǎn)單的遍歷怎么樣?

public?List<Integer>?forEach(BenchMarkState state){List<Integer> result =?new?ArrayList<>(state.testData.size());for(Integer item : state.testData) {result.add(item);}return?result; }

?

這個(gè)主意不錯(cuò),不過(guò)它的效率也不高,因?yàn)槌跏蓟粋€(gè)新的 ArrayList 同樣需要消耗資源。

Benchmark ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Mode ?Cnt ?Score ? Error ?Units TestLoopPerformance.forCStyle ? ? ? ? ? ? ? avgt ?200??6.013?±?0.108??ms/op TestLoopPerformance.forCStyleWithIteration ?avgt ?200??4.281?±?0.049??ms/op TestLoopPerformance.forEach?? ? ? ? ? ? ? ? avgt ?200??4.498?±?0.026??ms/op

?

HashMap (使用 HashMap<E,Object> 的 HashSet) 不是為遍歷所有元素設(shè)計(jì)的。遍歷一個(gè) HashMap 最快的方法是把 Iterator 和 C 語(yǔ)言形式結(jié)合起來(lái),這樣 JVM 就不會(huì)去調(diào)用 hasNext()。

?

結(jié)論


Foreach 和 Steam API 用來(lái)處理集合是很方便的。你可以更快的寫代碼。不過(guò),如果你的系統(tǒng)很穩(wěn)定,性能是一個(gè)主要的考量,你應(yīng)該考慮一下重寫你的循環(huán)。

總結(jié)

以上是生活随笔為你收集整理的高效遍历Java容器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久人人爽人人爽人人av | 日韩欧美亚洲国产 | 中文字字幕在线中文乱码电影 | 国产二区精品视频 | 四虎精品成人免费网站 | 欧美精品一区二区久久婷婷 | 日日噜噜噜夜夜爽爽狠狠视频97 | 93看片淫黄大片一级 | 成人综合区 | 亚洲欧美综合网 | 国产成人精品一区二区色戒 | 日韩伦理一区二区 | 一卡二卡在线 | aaa久久 | 国产一区二区伦理 | 少妇色综合 | 夜久久久 | 美女色网站 | 国产成人无码一区二区在线播放 | 色丁香av| 婷婷伊人综合 | 亚洲av片在线观看 | 波多野42部无码喷潮 | 男插女视频网站 | 在线观看欧美一区二区三区 | 91久久精品一区二区三区 | 国产在线拍揄自揄拍无码 | 中文字幕乱码中文字幕 | 日本黄色三级网站 | 日本成人片在线 | 色姑娘久| 国产三级视频在线播放 | 精品无码久久久久 | 成人福利网站在线观看 | 欧美一级色图 | 亚洲国产成人精品一区二区三区 | 亚洲tv在线| 日本一区高清 | 二区久久| 黄色污污网站在线观看 | 亚洲高清在线视频 | 亚瑟av| 黑人巨大精品一区二区在线 | 亚洲人女屁股眼交6 | 漂亮人妻被黑人久久精品 | 尤物国产| 亚洲精品成人无码熟妇在线 | 男女男精品视频站 | 黄色一级片a | 中文字幕av播放 | 欧美韩日一区二区 | 超碰2020| 天天撸一撸 | 国产午夜电影在线观看 | 特级av| 久久天天躁狠狠躁夜夜av | 日韩中文字幕av在线 | 欧美××××黑人××性爽 | 欧美看片 | 日韩av首页 | 国产成人午夜精品无码区久久 | 91精品视频网站 | 成人黄色免费视频 | 欧美日韩在线国产 | 欧美aaaaaaa | 中文字幕在线播放一区二区 | 国产成人精品999在线观看 | 91精品国产高清一区二区三区蜜臀 | 少妇人妻一级a毛片 | 国产精品111| 五月少妇 | 亚洲精品一区二三区 | 欧美亚洲一 | 无码国内精品人妻少妇蜜桃视频 | 日韩性大片 | 中文字幕黄色片 | 精品一区二区三区不卡 | 国产1页 | 91视频一区 | 色综合久久88色综合天天 | 国产日韩一区二区 | 草av在线 | 国产字幕侵犯亲女 | 高清国产一区二区 | 女性毛片| 亚洲色图另类小说 | 久久男人天堂 | 成人在线观看免费网站 | 特大黑人巨人吊xxxx | 一区二区内射 | 亚洲精品一区二区三区蜜臀 | 色狠狠一区二区三区 | 一本色道久久综合亚洲精品小说 | 蜜桃臀av| 日韩美女在线 | 男人天堂成人网 | 成人免费入口 | 亚洲乱码一区二区 | av网站在线免费看 |