Which is Faster For Loop or For-each in Java
對于Java回圈中的For和For-each,哪個更快
通過本文,您可以了解一些集合遍歷技巧,

Java遍歷集合有兩種方法,一個是最基本的for回圈,另一個是jdk5引入的for each,通過這種方法,我們可以更方便地遍歷陣列和集合,但是你有沒有想過這兩種方法?哪一個遍歷集合更有效?
for-each實作方法
For-each不是一種新語法,而是Java的語法糖(語法糖百度百科),在編譯時,編譯器將此代碼轉換為迭代器實作,并將其編譯為位元組碼,我們可以通過執行命令javap-verbose-Testforeach反編譯以下編譯代碼:
public class TestForeach {
List<Integer> integers;
public void testForeach(){
for(Integer i : integers){
}
}
}
獲得的詳細位元組碼如下:
public void testForeach();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: aload_0
1: getfield #2 // Field integers:Ljava/util/List;
4: invokeinterface #3, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
9: astore_1
10: aload_1
11: invokeinterface #4, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
16: ifeq 32
19: aload_1
20: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
25: checkcast #6 // class java/lang/Integer
28: astore_2
29: goto 10
32: return
LineNumberTable:
line 11: 0
line 13: 29
line 14: 32
LocalVariableTable:
Start Length Slot Name Signature
29 0 2 i Ljava/lang/Integer;
0 33 0 this Ltest/TestForeach;
}
此位元組碼的一般含義是使用getfileld命令來獲取integers變數并且呼叫List.iterator來獲取迭代器實體和呼叫iterator.hasNext,如果回傳true,呼叫iterator.next方法,
請看,這是迭代器遍歷集合的實作邏輯,
基準測驗
現在讓我們使用for回圈方法和for-each方法進行測驗,
public class ForLoopTest {
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < 10000000; i++) {
arrayList.add(i);
}
long arrayListStartTime = System.currentTimeMillis();
for (int i = 0; i < arrayList.size(); i++) {
arrayList.get(i);
}
long arrayListCost =System.currentTimeMillis()-arrayListStartTime;
System.out.println("ArrayList for loop traversal cost: "+ arrayListCost);
long arrayListForeachStartTime = System.currentTimeMillis();
for (Integer integer : arrayList) {
}
long arrayListForeachCost =System.currentTimeMillis()-arrayListForeachStartTime;
System.out.println("ArrayList foreach traversal cost: "+ arrayListForeachCost);
這是測驗結果:

如你所見,結果是顯而易見的,對于ArrayList,使用For回圈方法的性能優于For each方法,
我們可以說for回圈比for-each好嗎?
答案是否定的,在下一個基準測驗中,我們將ArrayList更改為LinkedList,
同樣,這里是測驗結果,

原因分析
一些初學者可能想知道為什么ArrayList使用for回圈方法遍歷得更快,而LinkedList則更慢,速度也非常慢?
這由ArrayList和LinkedList資料結構決定,
ArrayList底層使用陣列存盤元素,陣列是連續的記憶體空間,資料可以通過索引獲得,時間復雜度為O(1),因此速度很快,
LinkedList的底層是一個雙向鏈表,使用for回圈實作遍歷,每次都需要從鏈表的頭節點開始,時間復雜度為O(n*n),
結論
- 使用ArrayList時,for回圈方法更快,因為for-each由迭代器實作,并且需要執行并發修改驗證,
- 使用LinkedList時,for-each比for回圈快得多,因為LinkedList是通過使用雙向鏈表實作的,每個尋址都需要從頭節點開始,如果我們需要遍歷LinkedList,我們需要避免使用for回圈,
- 使用迭代器模式,for-each不需要關心集合的具體實作,如果需要替換集合,無需修改代碼即可輕松替換,
歡迎關注公眾號:愚生淺末,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501986.html
標籤:其他
上一篇:在使用amoeba連接資料庫時,報錯java.lang.Exception: poolName=slaves, no valid pools
