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

时间:2022-12-17 15:14:22

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

常见的实现方法:

1.for循环:

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

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

2.foreach:

  1. for(Object obj : list)

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

3.while:

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

4.迭代:

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

测试代码:

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

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

输出结果(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()方法将数组内容输出,难道他不知道这个操作耗时非常大吗,这样计算出的结果有什么用处呢。

Java中迭代列表中数据时几种循环写法的效率比较的更多相关文章

  1. salesforce lightning零基础学习&lpar;七&rpar; 列表展示数据时两种自定义编辑页面

    上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息.当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:Pop Up Window弹出修改详情以 ...

  2. C&num;程序中从数据库取数据时需注意数据类型之间的对应,int16&bsol;int32&bsol;int64

    private void btn2_Click(object sender, RoutedEventArgs e)         {             using (SqlConnection ...

  3. asp&period;net mvc视图中使用entitySet类型数据时提示出错

    asp.net mvc5视图中使用entitySet类型数据时提示以下错误 检查了一下引用,发现已经引用了System.Data.Linq了,可是还是一直提示出错, 后来发现还需要在Views文件夹下 ...

  4. SQL中使用UPDATE更新数据时一定要记得WHERE子句

    我们在使用 SQL 中的 UPDATE 更新数据时,一般都不会更新表中的左右数据,所以我们更新的数据的 SQL 语句中会带有 WHERE 子句,如果没有WHERE子句,就回更新表中所有的数据,在 my ...

  5. selenium&plus;java:获取列表中的值

    selenium+java:获取列表中的值 (2011-08-23 17:14:48) 标签: 杂谈 分类: selenium 初步研究利用java+testNg框架下写selenium测试用例,今天 ...

  6. ArcGIS客户端API中加载大量数据的几种解决办法

    ArcGIS客户端API中加载大量数据的几种解决办法 2011-03-25 18:17 REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Sil ...

  7. java中对集合对象list的几种循环访问

    java中对集合对象list的几种循环访问的总结如下 1 经典的for循环 public static void main(String[] args) { List<String> li ...

  8. &lpar;转&rpar;java中对集合对象list的几种循环访问总结

    Java集合的Stack.Queue.Map的遍历   在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...

  9. Java构造和解析Json数据的两种方法详解二

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Jso ...

随机推荐

  1. Ecshop 单选按钮组功能 颜色多选

    效果: js代码: function changeAtt(t,src,key) { document.getElementById('spec_value_'+src).checked='checke ...

  2. 蚂蚁【A001】

    [1005]出自附中练习场,其他编号(1005)[难度A]——————————————————————————————————————————————————————————————————————— ...

  3. 《BI那点儿事》SSRS图表和仪表——雷达图分析三国超一流谋士、统帅数据(图文并茂)

    雷达图分析三国超一流谋士.统帅数据,献给广大的三国爱好者们,希望喜欢三国的朋友一起讨论,加深对传奇三国时代的了解 建立数据环境: -- 抽取三国超一流谋士TOP 10数据 DECLARE @t1 TA ...

  4. 从jsTree演示代码中提取的在线文件查看

    从jsTree演示代码中提取的在线文件查看 jsTree 请参考:https://www.jstree.com/ 效果如下: 代码下载:http://files.cnblogs.com/files/z ...

  5. C&num;&colon;常规属性和自动实现的属性

    根据属性的实现方式,属性可分为自动实现的属性和常规属性. 常规属性需要具体的人为的实现get访问器或者set访问器,而且一般需要有一个字段与之相对应:而自动实现的属性的get和set访问器的实现部分被 ...

  6. 数字图像处理&lpar;MATLAB版&rpar;学习笔记&lpar;2&rpar;——第2章 灰度变换与空间滤波

    0.小叙闲言 1.本章整体结构 2.书中例子 例2.1 主要是使用函数imadjust,来熟悉一下灰度处理,体验一把 >> imread('myimage.jpg'); >> ...

  7. c&num;编程-线程同步

    线程同步 上一篇介绍了如何开启线程,线程间相互传递参数,及线程中本地变量和全局共享变量区别. 本篇主要说明线程同步. 如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏.如果 ...

  8. SpringMVC框架学习笔记(4)——结果跳转方式

    1.设置ModelAndView对象.根据View和视图解析器跳转到指定页面(视图解析器前缀+viewname+视图解析器后缀) @Override public ModelAndView handl ...

  9. ubuntu python3和python2切换脚本

    最近在ubuntu上开发较多,有些工具只能在python2运行,而开发又是在python3上做的开发,所以写个脚本方便在python2和python3之间切换. 切换成python2的文件usepy2 ...

  10. 织梦DedeCMS实现 三级栏目&lowbar;二级栏目&lowbar;一级栏目&lowbar;网站名称 的效果代码

    1.将官方原来的排列方式反过来,找到include/typelink.class.php第164行 $this->valuePositionName = $tinfos['typename']. ...