今日看到@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文档中的描述矛盾了。

至此,原因未知,如有知情者,欢迎在下方评论解释一下,指导指导大家。

如本文中有错误,恳请指出,感激不尽。

最新文章

  1. 【转】}目前比较全的CSS重设(reset)方法总结
  2. List的遍历和删除元素
  3. RM报表里的变量
  4. PE安装原版XP系统(含高版本PE安装选项灰色处理办法)
  5. PLSQL_基础系列07_插入方式Pivoting / Unconditional / Conditional ALL / Conditional FIRST INSERT(案例)
  6. POJ 3096 Surprising Strings(STL map string set vector)
  7. hdoj 2098 分拆素数和
  8. complex(x):创建一个复数
  9. 配置免安装版JAVA1.7的环境变量
  10. IOS中TableView的使用(1) -创建一个简单的tableView
  11. rabbitmq-message(C#)
  12. StreamReader和StreamWriter说明
  13. Ramnit 蠕虫分析
  14. Python设计模式 - UML - 类图(Class Diagram)
  15. (1.10)SQL优化——mysql 常见SQL优化
  16. mysql-5.5.50-winx64
  17. GsonFormat的使用 (转)
  18. 转载文章CSS3的calc()使用
  19. 奇怪吸引子---Finance
  20. [svc]为何linux ext4文件系统目录默认大小是4k?

热门文章

  1. Java实现 LeetCode 208 实现 Trie (前缀树)
  2. Java实现 LeetCode 143 重排链表
  3. Java实现 LeetCode 14 最长公共前缀
  4. java实现输入信用卡号码
  5. java实现第六届蓝桥杯移动距离
  6. 利用tcpdump命令统计http的GET和POST请求
  7. 使用root配置的hadoop并启动会出现报错
  8. 温故知新-java多线程&amp;深入理解线程池
  9. 【Flutter实战】移动技术发展史
  10. 在WinForms里嵌入MediaPlayer的一些版本问题, tlbimp导入, 以及不导入而纯用C#+字符串来动态调用.