日韩性视频-久久久蜜桃-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免费观看 | 成人av视屏 | 7777久久亚洲中文字幕 | 97青草| 女人18毛片水真多 | 欧美专区 日韩专区 | 亚洲人成网站999久久久综合 | 欧美激情亚洲色图 | 极品蜜桃臀肥臀-x88av | 国产九九精品视频 | 日韩啪啪网 | 亚洲啪视频 | www.久久久 | 国产夫妻视频 | www,超碰| 午夜美女福利 | 麻豆传媒观看 | 久久免费视频网 | 美国一区二区三区 | 中国一级片黄色一级片黄 | 在线观看亚洲精品 | 饥渴放荡受np公车奶牛 | 午夜鲁鲁 | 日韩黄色精品 | 图片区偷拍区小说区 | 亚洲欧美综合精品久久成人 | 国产中文字幕亚洲 | xx性欧美肥妇精品久久久久久 | 乱老熟女一区二区三区 | 天天射寡妇射 | 福利所导航 | 欧美一区二区三区电影 | 成人av入口 | 亚洲三级免费 | 男ji大巴进入女人的视频 | 尤物在线精品 | 日b免费视频 | 卡一卡二av | 99re视频在线 | 性色av网站 | 精品久久久中文字幕人妻 | 无码人妻丰满熟妇区96 | 伊久久 | 少妇无套内谢久久久久 | 国产精品无码99re | 中文字幕在线免费 | 好姑娘在线观看高清完整版电影 | 国产高清免费观看 | 色香蕉在线 | 四虎永久免费在线观看 | 久久婷婷五月综合色吧 | 少妇久久久久久久 | 亚洲精品国产精品乱码在线观看 | 欧美毛片视频 | jizz日本大全| 日韩少妇一区 | 毛片内射久久久一区 | 欧美老肥妇做.爰bbww视频 | 精品一区二区久久久久久久网站 | 精品伦理一区二区 | 超碰蜜桃 | 91亚洲在线 | 日本美女毛茸茸 | 国产精品无码白浆高潮 | 五月婷婷激情 | 超碰在线c | 亚洲精品一区二区在线观看 | 久久精品第一页 | 岛国av噜噜噜久久久狠狠av | 少妇性l交大片免费观看 | 影音先锋中文字幕在线视频 | 久久久123 | 国产福利午夜 | 一级黄色大全 | 日韩免费毛片 | 久久精品视频观看 | 一级黄网站 | yy4138理论片动漫理论片 | 国产精品午夜在线观看 | 夜夜伊人 | 国产成人无码精品久久久电影 | 黑人中文字幕一区二区三区 | 河北彩花中文字幕 | 国产精久久一区二区三区 | 97超碰免费在线 | 老头吃奶性行交 | 欧美日韩中文字幕一区二区 | missav|免费高清av在线看 | 日韩欧美久久久 | 丰满少妇被猛烈进入无码 | 免费在线日韩av | 毛片无遮挡 | 国产永久免费观看 | xx69欧美| 亚洲淫片 | 自拍愉拍| 欧美国产一二三区 | 久久夜精|