关于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 接口,就可以完成遍历操作(即依次处理该数据结构的所有 ...
随机推荐
- 多线程与RunLoop
iOS开发中的多线程 一个iOS程序,默认开启1条线程--主线程orUI线程 主线程主要作用: 显示/刷新UI界面 处理UI事件(点击.滚动.拖拽事件等) 主线程使用注 ...
- Java实现 LeetCode 779 第K个语法符号(递归)
779. 第K个语法符号 在第一行我们写上一个 0.接下来的每一行,将前一行中的0替换为01,1替换为10. 给定行数 N 和序数 K,返回第 N 行中第 K个字符.(K从1开始) 例子: 输入: N ...
- Java实现 LeetCode 725 分隔链表(暴力)
725. 分隔链表 给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分. 每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 nu ...
- Java实现 LeetCode 720 词典中最长的单词(字典树)
720. 词典中最长的单词 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最 ...
- Java实现 LeetCode 面试题62. 圆圈中最后剩下的数字(约瑟夫环)
面试题62. 圆圈中最后剩下的数字 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆 ...
- Java实现 蓝桥杯VIP 算法提高 林丹大战李宗伟
问题描述 我们用0表示林丹,1表示李宗伟. 输入数据中每行会给出一个0或者1,表示对应选手得1分. 当一方得分达到21分时,只要该方与对方分差超过1分,该方即胜出. 你需要输出最后获胜选手的代号. 输 ...
- Java实现俄式乘法
1 问题描述 首先,了解一下何为俄式乘法?此处,借用<算法设计与分析基础>第三版上一段文字介绍: 2 解决方案 package com.liuzhen.chapter4; public c ...
- java代码(15) ---java8 Function 、Consumer 、Supplier
Java8 Function.Consumer.Supplier 有关JDK8新特性之前还有三篇博客: 1,java代码(1)---Java8 Lambda 2,java代码(2)---Java8 S ...
- 哪些年,我们玩过的Git
作者:玩世不恭的Coder公众号:玩世不恭的Coder时间:2020-06-05说明:本文为原创文章,未经允许不可转载,转载前请联系作者 哪些年,我们玩过的Git 前言一.前期工作常用基本概念的理解G ...
- WinUI 3试玩报告
1. 什么是 WinUI 3 在微软 Build 2020 开发者大会上,WinUI 团队宣布可公开预览的 WinUI 3 Preview 1,它让开发人员可以在 Win32 中使用 WinUI.Wi ...