文档章节

Java中迭代列表中数据时几种循环写法的效率比较

EDIAGD
 EDIAGD
发布于 2013/09/26 13:42
字数 868
阅读 128
收藏 0

Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较。虽然网上已经有了类似的文章,但是对他们的结论并不认同。

常见的实现方法:

1.for循环:

[java]  view plain copy print ?

  1. for(int i = 0; i < list.size(); i++)  
  2. for(int i = 0, size = list.size(); i < size; i++)  

 

一般人都会认为第二种写法效率高。

 

 

2.foreach:

 

 

[java]  view plain copy print ?

  1. for(Object obj : list)  


这是一种简洁的写法,只能对列表进行读取,无法修改。

 

3.while:

[java]  view plain copy print ?

  1. int size = list.size();  
  2. while(size-- > 0)  


4.迭代:

[java]  view plain copy print ?

  1. Object iter = list.iterator();  
  2. while(iter.hasNext()) {  
  3.   iter.next();  
  4. }  

 

测试代码:

 针对以上几种方法编写的测试代码。

[java]  view plain copy print ?

  1. public static void main(String[] args) {  
  2.       List<Integer> list = new ArrayList<Integer>();  
  3.   
  4.       int runTime = 1000;//执行次数  
  5.       for (int i = 0; i < 1000 * 1000; i++) {  
  6.           list.add(i);  
  7.       }  
  8.       int size = list.size();  
  9.       long currTime = System.currentTimeMillis();//开始分析前的系统时间  
  10.       //基本的for              
  11.       for(int j = 0; j < runTime; j++) {  
  12.           for (int i = 0; i < size; i++) {  
  13.               list.get(i);  
  14.           }  
  15.       }  
  16.       long time1 = System.currentTimeMillis();  
  17.   
  18.       //foreach  
  19.       for(int j = 0; j < runTime; j++) {  
  20.           for (Integer integer : list) {  
  21.           }  
  22.       }  
  23.       long time2 = System.currentTimeMillis();  
  24.   
  25.       for(int j = 0; j < runTime; j++) {  
  26.           //while  
  27.           int i = 0 ;  
  28.           while(i < size){  
  29.               list.get(i++);  
  30.           }  
  31.       }  
  32.       long time3 = System.currentTimeMillis();  
  33.   
  34.       for(int j = 0; j < runTime; j++) {//普通for循环  
  35.           for (int i = 0; i < list.size(); i++) {  
  36.               list.get(i);  
  37.           }  
  38.       }  
  39.       long time4 = System.currentTimeMillis();  
  40.   
  41.       for(int j = 0; j < runTime; j++) {//迭代  
  42.           Iterator<Integer> iter = list.iterator();  
  43.           while(iter.hasNext()) {  
  44.               iter.next();  
  45.           }  
  46.       }  
  47.       long time5 = System.currentTimeMillis();  
  48.   
  49.       long time = time1 - currTime ;  
  50.       System.out.print("use for:" + time);  
  51.       time = time2 - time1;  
  52.       System.out.print("\tuse foreach:" + time);  
  53.       time = time3 - time2;  
  54.       System.out.print("\tuse while:" + time);  
  55.       time = time4 - time3;  
  56.       System.out.print("\tuse for2:" + time);  
  57.       time = time5 - time4;  
  58.       System.out.print("\tuse iterator:" + time);  
  59.       System.out.println();  
  60.   }  

 

输出结果(JDK1.6):

 

1.

use for:8695        use foreach:17091        use while:6867        use for2:7741        use iterator:14144

2.

use for:8432        use foreach:18126        use while:6905        use for2:7893        use iterator:13976

3.

use for:8584        use foreach:17177        use while:6875        use for2:7707        use iterator:14345
 

结论:

1.针对列表的 foreach的效率是最低:

耗时是普通for循环的2倍以上。个人理解它的实现应该和iterator相似。

2. list.size()的开销很小:

list.size()次数多少对效率基本没有影响。查看ArrayList的实现就会发现,size()方法的只是返回了对象内的长度属性,并没有其它计算,所以只存在函数调用的开销。

对数组的测试:

将代码中的列表list换做数组再进行测试(iterator不适用),发现耗时基本为0。说明:

 

3. 列表的get()方法开销不少

应该主要是检测数据合法性时产生的。

将执行次数增加100万倍,这时可以看出结果基本相等,并没有明显的差异。说明:

4. 数组length也没有开销

可见数组长度并不是每次执行的时候都要计算的。联想一下Java创建数组的时候要求必须指定数组的长度,编译处理的时候显然没有把这个值抛弃掉。

 

网上有一篇类似的文章,它居然得出了一个foreach执行效率最高的结论。看一下它的测试代码就会发现一个要命的问题,它居然在执行每次循环的时候调用了System.out.print()方法将数组内容输出,难道他不知道这个操作耗时非常大吗,这样计算出的结果有什么用处呢。

后续有很多开发填坑的文章发布,如果对你有帮助,请支持和加关注一下

http://e22a.com/h.05ApkG?cv=AAKHZXVo&sm=339944

https://shop119727980.taobao.com/?spm=0.0.0.0 

本文转载自:http://blog.csdn.net/waynell/article/details/6674959

共有 人打赏支持
EDIAGD
粉丝 49
博文 149
码字总数 58327
作品 0
嘉定
后端工程师
私信 提问
Java编程学习:集合框架详解

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰
05/30
0
0
12-《深度拆解JVM》之垃圾回收(上)

一、问题引入 你应该听说过这么一句话:免费的其实是最贵的。 Java 虚拟机的自动内存管理,将原本需要由开发人员手动回收的内存,交给垃圾回收器来自动回收。不过既然是自动机制,肯定没法做...

飞鱼说编程
10/26
0
0
Java Connection集合分析之List

Java Connection集合家庭分析 Java集合大致可以分为Set、List、Queue和Map四种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合,Java 5 ...

我爱春天的毛毛雨
11/14
0
0
Velocity初探小结--velocity使用语法详解

  做java开发的朋友一般对JSP是比较熟悉的,大部分人第一次学习开发View层都是使用JSP来进行页面渲染的,我们都知道JSP是可以嵌入java代码的,在远古时代,java程序员甚至在一个jsp页面上就完成...

冬至饮雪
2016/11/19
0
0
自己动手实现java数据结构(一) 向量

1.向量介绍   计算机程序主要运行在内存中,而内存在逻辑上可以被看做是连续的地址。为了充分利用这一特性,在主流的编程语言中都存在一种底层的被称为数组(Array)的数据结构与之对应。在使...

小熊餐馆
11/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

C4C销售订单行项目价格维护方法

需求很简单,能够创建销售订单,在行项目里添加产品,带出价格来,同时把总价显示在销售订单抬头区域。 如下图所示: 下面是具体配置。 Business Configuration里,点击Sales Order的配置: ...

JerryWang_SAP
40分钟前
9
0
deepin中配置robot framework环境

本文永久更新地址:https://my.oschina.net/bysu/blog/2989005 【若要到岸,请摇船:开源中国 不最醉不龟归】 1.在终端中输入pip,回车,如果提示没有该命令,则先安转pip sudo apt-get inst...

不最醉不龟归
今天
8
0
OSChina 周日乱弹 —— 钱不还,我就当你人不在了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享Bigleaf的单曲《小鹿》 《小鹿》- Bigleaf 手机党少年们想听歌,请使劲儿戳(这里) 周日在家做什么? 做手工呀, @poorfis...

小小编辑
今天
200
5
EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
23
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
33
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部