在翻看Java相关的面试题时看到一个问题,普通for循环和for-each的效率孰优孰劣?
于是写了一个简单的例子做了一些对比,如下:
package com.yummy.nowcoder; import java.util.ArrayList; import java.util.Calendar; import java.util.Iterator; import java.util.LinkedList; /** * Created by qq985 on 2017/3/13. */ public class TestForTime { public static void main(String[] args) { ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i < 100000000; i++) { arrayList.add(1); } long startTime; long endTime; System.out.println("=======对ArrayList操作======="); startTime = Calendar.getInstance().getTimeInMillis(); int size = arrayList.size(); for (int i = 0; i < size; i++) { } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("空循环耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); int size2 = arrayList.size(); for (int i = 0; i < size2; i++) { int iValue = arrayList.get(i); } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("普通for循环,使用get()耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); for (int iValue : arrayList) { } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("for-each耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); Iterator iterator = arrayList.iterator(); while (iterator.hasNext()) { int iValue = (int) iterator.next(); } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("使用Iterator耗时:" + (endTime - startTime)+"ms"); LinkedList<Integer> linkedList = new LinkedList<>(); for (int i = 0; i < 100000; i++) { linkedList.add(1); } System.out.println("=======对LinkedList操作======="); startTime = Calendar.getInstance().getTimeInMillis(); int size3 = linkedList.size(); for (int i = 0; i < size3; i++) { } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("空循环耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); int size4 = linkedList.size(); for (int i = 0; i < size4; i++) { int iValue = linkedList.get(i); } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("普通for循环,使用get()耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); for (int iValue : linkedList) { } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("for-each耗时:" + (endTime - startTime)+"ms"); startTime = Calendar.getInstance().getTimeInMillis(); Iterator iterator2 = linkedList.iterator(); while (iterator2.hasNext()) { int iValue = (int) iterator2.next(); } endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("使用Iterator耗时:" + (endTime - startTime)+"ms"); } }
实验中,分别使用了ArrayList和LinkedList作为操作对象,结果如下:
=======对ArrayList操作=======
空循环耗时:27ms
普通for循环,使用get()耗时:126ms
for-each耗时:257ms
使用Iterator耗时:180ms
=======对LinkedList操作=======
空循环耗时:2ms
普通for循环,使用get()耗时:3495ms
for-each耗时:3ms
使用Iterator耗时:3ms
Process finished with exit code 0
由运行结果可以看出,若以ArrayList作为操作对象,for-each的效率比普通for循环低许多,但是若以LinkedList作为操作对象,for-each的效率与普通for循环的效率不在一个量级,原因也是因为对LinkedList使用了get(index),导致每次访问数据需从链表头开始遍历,耗时增加。