关于for循环和Iterator遍历ArrayList的性能问题
今日看到@DriveMan的一篇博客,题为《ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口?》,文中提到对于实现了RandomAccess接口的类来说,使用for循环遍历比使用Iterator遍历更加高效快速。
由于本人之前没了解过这方面的知识,阅此博客后心怀好奇便去查阅了API文档了解了一下,官网的介绍是这样的:
Marker interface used by List implementations to indicate that they support fast (generally constant time) random access. The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.
上面这段话的意思就是:RandomAccess是一个标记接口,用于标明实现了该接口的List支持快速随机访问。并且指出了该接口的主要用途是当随机或顺序访问一些List时,允许泛型算法改变它们的行为来提升性能。
此外,官方还列举了一个例子,提到使用for循环遍历的速度会比Iterator遍历的速度要快。原文如下:
for (int i=0, n=list.size(); i < n; i++)
list.get(i);
runs faster than this loop:
for (Iterator i=list.iterator(); i.hasNext(); )
i.next();
在@DriveMan的文中,测试了for与Iterator遍历ArrayList的性能,结论与官网描述一致,for循环稍快与Iterator。
怀着一颗好奇心,本人也想试试看是否真的如此,于是也开始了测试。话不多说,直接上代码和结果:
public class ArrayListDemo {
public static void main(String[] args) {
//存储一些数据到集合中
List<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < 50000; i++) {
arrayList.add(i);
}
System.out.println("for遍历ArrayList:" + arrayListFor(arrayList));
System.out.println("Iterator遍历ArrayList:" + arrayListIterator(arrayList));
}
//使用for循环遍历ArrayList
public static long arrayListFor(List<Integer> arrayList) {
long start = System.currentTimeMillis();
for (int i = 0; i < arrayList.size(); i++) {
arrayList.get(i);
}
long end = System.currentTimeMillis();
return end - start;
}
//使用Iterator遍历ArrayList
public static long arrayListIterator(List<Integer> arrayList) {
long start = System.currentTimeMillis();
for (Iterator i = arrayList.iterator(); i.hasNext();) {
i.next();
}
long end = System.currentTimeMillis();
return end - start;
}
}
首先我准备了50000条数据进行测试,这与@DriveMan文中是一致的,这样方便对比。运行5次后,结果如下:
50000条数据时的测试结果
遍历方式 第1次运行 第2次运行 第3次运行 第4次运行 第5次运行
for 5 ms 3 ms 4 ms 5 ms 4 ms
Iterator 5 ms 4 ms 5 ms 5 ms 3 ms
由以上结果可以看到,50000条数据时,for循环略占优一些(但第5次运行是Iterator占优)。
由于数据量过少,for优势好像不是很明显,于是我将数据量改为50000000,再次测试for与Iterator的性能并进行对比,测试结果如下:
50000000条数据时的测试结果
遍历方式 第1次运行 第2次运行 第3次运行 第4次运行 第5次运行
for 52 ms 47 ms 56 ms 50 ms 45 ms
Iterator 15 ms 12 ms 11 ms 15 ms 11 ms
奇怪的现象出现了!50000000条数据时,for遍历耗费的时间基本都是Iterator的4倍左右!for循环遍历完全落入下风!
反复测试之,依旧如此,这似乎与官网API文档中的描述矛盾了。
至此,原因未知,如有知情者,欢迎在下方评论解释一下,指导指导大家。
如本文中有错误,恳请指出,感激不尽。
关于for循环和Iterator遍历ArrayList的性能问题的更多相关文章
- 迭代器 iterator(二): 用iterator遍历arraylist
迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址.迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些 ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转)
主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析
最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转载)
原文地址: http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 原文地址: http://www.trinea.cn ...
- 【转】ArrayList和LinkedList的几种循环遍历方式及性能对比分析
原文网址:http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 主要介绍ArrayList和LinkedList这两种 ...
- Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 [ 转载 ]
Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 @author Trinea 原文链接:http://www.trinea.cn/android/arrayl ...
- (转)ArrayList和LinkedList的几种循环遍历方式及性能对比分析
主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...
- java 数据类型:集合接口Collection之常用ArrayList;lambda表达式遍历;iterator遍历;forEachRemaining遍历;增强for遍历;removeIf批量操作集合元素(Predicate);
java.util.Collection接口 Java的集合主要由两个接口派生出来,一个是Collection一个是Map,本章只记录Collection常用集合 集合只能存储引用类型数据,不能存储基 ...
- ES6学习笔记(十三)Iterator遍历器和for...of循环
1.概念 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有 ...
随机推荐
- 【HIVE & Spark】将hive引擎换成Spark,运行速度快!怎么换?请看本文
本教程仅仅是使用spark,能在hive用就行. 1.下载Spark; 2.WinSCP上传spark压缩包到虚拟机: 3.tar -zxvf spark-2.3.3-bin-without-hado ...
- SpringBoot 定制 starter 启动器
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 在实际项目开发中,我们常常会用到各种各样的 starter,这些starter 有的是有 springb ...
- Java实现 LeetCode 399 除法求值
399. 除法求值 给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字.根据已知方程式求解问题,并返回计算结果.如果结果不存在,则返回 -1.0. 示例 ...
- Java实现 LeetCode 51 N皇后
51. N皇后 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后问题的解决 ...
- Java实现 蓝桥杯 历届真题 数字拆分
正整数可以表示为若干正整数的累加和. 如,对于正整数n=6,可以分划为: 5+1 4+2 4+1+1 3+3 3+2+1 3+1+1+1 2+2+2 2+2+1+1 2+1+1+1+1 1+1+1+1 ...
- Java实现 LeetCode 9 回文数
9. 回文数 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false ...
- Java实现俄式乘法
1 问题描述 首先,了解一下何为俄式乘法?此处,借用<算法设计与分析基础>第三版上一段文字介绍: 2 解决方案 package com.liuzhen.chapter4; public c ...
- java实现报数游戏
报数游戏 有n个孩子站成一圈,从第一个孩子开始顺时针方向报数,报到3的人出列,下一个人继续从1报数,直到最后剩下一个孩子为止.问剩下第几个孩子.下面的程序以10个孩子为例,模拟了这个过程,请完善之(提 ...
- Mybatis多表操作
一:引言 在学习完前面的mybatis基本语法后,大家都有个认知,这个Mybatis太强大了,比之前使用JDBC写方便多了,但是你们当初在使用原生JDBC写SQL查询的时候有没有遇到过多表查询呢?肯定 ...
- iOS-Core Foundation框架到Foundation桥接的三种方式
温故知新.勤总结,才能生巧!这次总结一下 :Core Foundation框架到Foundation桥接的三种方式 Foundation提供OC的基础类(像NSObject).基本数据类型等. Cor ...