方法一:普通for循环遍历
//仅做代码的格式说明,不涉及具体问题
for(int i = 0 ; i < list.size() ; i++){
system.out.println(list.get(i));
}
方法二:增强for循环遍历
增强for循环的底层也是Iterator实现的,只是对它包装了一下。
for(String string:list){
system.out.println(string);
}
方法三:Iterator迭代器遍历
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
这三种方式哪一种效率最高呢?让我们来测试一下:
//测试代码,三种方式遍历8000000条信息
public class ArrayListTest {
private static List<String> list = new ArrayList<String>();
public static void main(String[] args) {
ArrayListTest test = new ArrayListTest();
test.initList(list);
test.forList(list);
test.forEachList(list);
test.iteratorList(list);
}
//在List里面添加8000000条信息
public List<String> initList(List<String> list){
int num = 8000000;
for(int i = 0; i < num; i++){
list.add("ListTest"+i);
}
return list;
}
//普通for循环遍历
public void forList(List<String> list){
long start = System.currentTimeMillis();
for(int i = 0; i < list.size(); i++){
String value = list.get(i);
}
long end = System.currentTimeMillis();
long usedTime = end - start;
System.out.println("普通for循环遍历时间:"+usedTime);
}
//增强for循环遍历
public void forEachList(List<String> list){
long start = System.currentTimeMillis();
for(String string:list){
String value = string;
}
long end = System.currentTimeMillis();
long usedTime = end - start;
System.out.println("增强for循环遍历时间:"+usedTime);
}
//Iterator迭代器遍历
public void iteratorList(List<String> list){
long start = System.currentTimeMillis();
Iterator<String> it = list.iterator();
while(it.hasNext()){
String value = (String) it.next();
}
long end = System.currentTimeMillis();
long usedTime = end - start;
System.out.println("Iterator迭代器遍历时间:"+usedTime);
}
}
在做同样操作的情况下,结果相当随机,并没有明显的差别,测试结果如下
普通for循环遍历时间:109
增强for循环遍历时间:114
Iterator迭代器遍历时间:107
普通for循环遍历时间:90
增强for循环遍历时间:90
Iterator迭代器遍历时间:93
普通for循环遍历时间:88
增强for循环遍历时间:85
Iterator迭代器遍历时间:92
但是,如果只遍历,不做其他操作,差别非常明显,测试结果如下
普通for循环遍历时间:6
增强for循环遍历时间:116
Iterator迭代器遍历时间:12
普通for循环遍历时间:6
增强for循环遍历时间:98
Iterator迭代器遍历时间:14
普通for循环遍历时间:5
增强for循环遍历时间:83
Iterator迭代器遍历时间:15
耗时最短是传统的for循环,其次是iterator、增强for循环,也就是按下标遍历的方式的性能要高于迭代的方式。增强for循环的底层实现原理就是迭代器Iterator。如果是顺序访问下标的那些类实例,使用for循环去遍历。
在官方API文档中找到了说明,在遍历ArrayList时,普通for循环要比iterator快,以下摘自API:
public interface RandomAccess
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.
The best algorithms for manipulating random access lists (such as ArrayList) can produce quadratic behavior when applied to sequential access lists (such as LinkedList). Generic list algorithms are encouraged to check whether the given list is an instanceof this interface before applying an algorithm that would provide poor performance if it were applied to a sequential access list, and to alter their behavior if necessary to guarantee acceptable performance.
It is recognized that the distinction between random and sequential access is often fuzzy. For example, some List implementations provide asymptotically linear access times if they get huge, but constant access times in practice. Such a List implementation should generally implement this interface. As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:
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();
This interface is a member of the Java Collections Framework.
Since:
1.4