几种实现JAVA语言集合迭代的高性能方法讲解
小标 2018-09-11 来源 : 阅读 1238 评论 0

摘要:本文主要向大家介绍了几种实现JAVA语言集合迭代的高性能方法讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了几种实现JAVA语言集合迭代的高性能方法讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

几种实现Java集合迭代的高性能方法讲解
一、介绍
Java开发者经常会遇到处理集合(比如ArrayList、HashSet)的情况,Java 8也提供了Lambda表达式和Streaming API来简化集合相关的工作。在大多数应用场景下,无需考虑集合迭代的性能消耗。但是,在一些极端情况下,比如集合包含了上百万条记录的情况,这个时候集合迭代就需要选择正确的姿势,否则性能会较差。
使用JMH检查下面每段代码片段的运行时间。
二、forEach vs. C Style vs. Stream API
迭代是一个非常基本的功能,所有的编程语言都有简单的迭代语法,允许程序员在集合上运行迭代。Stream API可以通过Collections用非常直接的方式进行迭代。
public List streamSingleThread(BenchMarkState state) { List result = new ArrayList<>(state.testData.size()); state.testData.stream().forEach(item -> {  result.add(item); }); return result;} public List streamMultiThread(BenchMarkState state) { List result = new ArrayList<>(state.testData.size()); state.testData.stream().parallel().forEach(item -> {  result.add(item); }); return result;}
使用forEach循环也非常简单:
public List forEach(BenchMarkState state) { List result = new ArrayList<>(state.testData.size()); for(Integer item : state.testData) {  result.add(item); } return result;}
C style方式的迭代其代码要冗长一些,但仍然非常紧凑:
public List forCStyle(BenchMarkState state) { int size = state.testData.size(); List result = new ArrayList<>(size); for(int j = 0; j < size; j ++){  result.add(state.testData.get(j)); } return result;}

对于C style方式的迭代,JVM只是简单地增加了一个整型变量,它直接从内存读值。这使它非常快。但forEach迭代则不同,根据Oracle官方文档,JVM必须把forEach转换为迭代器并为每个数据项调用hasNext()。这就是为什么forEach比C style 迭代慢。
forEach文档:(https://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)
三、哪一种迭代的性能最高
我们定义测试数据:
@State(Scope.Benchmark)public static class BenchMarkState { @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); } public Set testData = new HashSet<>(500000);}
Java Set同时支持Stream API和forEach循环。根据前面的测试,如果我们把Set转换为ArrayList, 看看性能是否有所提升。
public List forCStyle(BenchMarkState state) { int size = state.testData.size(); List 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;}
C style组合迭代的循环:
public List forCStyleWithIteration(BenchMarkState state) {
int size = state.testData.size();
List result = new ArrayList<>(size);
Iterator iteration = state.testData.iterator();
for(int j = 0; j < size; j ++) {
result.add(iteration.next());
}
return result;
}
forEach:
public List forEach(BenchMarkState state) { List result = new ArrayList<>(state.testData.size()); for(Integer item : state.testData) {  result.add(item); } return result;}
看起来 代码简洁,但并不理想,因为初始化ArrayList比较消耗资源。
结论
在集合Collections上使用Foreach和Stream API是非常便利的方法,写这样的代码也显得精炼。但要记住,当系统需要考虑性能和稳定性因素时,就应该改写这些循环。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 1
看完这篇文章有何感觉?已经有1人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程