首頁 >Java >java教程 >For-Each 迴圈與迭代器:哪一個對於遍歷集合更有效?

For-Each 迴圈與迭代器:哪一個對於遍歷集合更有效?

DDD
DDD原創
2024-11-17 11:54:02486瀏覽

For-Each Loop vs. Iterator: Which is More Efficient for Traversing Collections?

確定效率:For-Each 循環與迭代器

在有效地遍歷集合時,出現了問題:哪種方法更優越- for-each 迴圈或迭代器?

傳統For 循環

傳統for 循環,通常稱為「c 風格」循環,範例了以下語法:

for(int i=0; i<list.size(); i++) {
   Object o = list.get(i);
}

For-Each 循環

Java Java 1.5 引入了增強的for-each 循環語法,它簡化了循環過程:

for (Integer integer : a) {
  integer.toString();
}

Iterator

Java 的迭代器抽象化提供了另一種遍歷集合的方法:

for (Iterator iterator = a.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   integer.toString();
}

效能差異

對於僅從集合中讀取值而不進行修改,在for-each 循環和迭代器之間進行選擇不會產生顯著的性能差異。兩種方法都在內部使用迭代器。

但是,在遍歷特定資料結構時,傳統的 for 迴圈可能比 for-each 迴圈或迭代器更有效率。例如,鍊錶需要 O(n) 運算才能使用 get(i) 擷取元素。這導致循環複雜度為 O(n2)。迭代器保證前進操作為 O(1),導致循環複雜度為 O(n)。

字節碼比較

比較兩個循環產生的字節碼類型說明了它們的等價性:

For -Each 循環字節碼:

ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 3
GOTO L2
L3
ALOAD 3
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 2
ALOAD 2
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L2
ALOAD 3
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L3

迭代器字節碼:

ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 2
GOTO L7
L8
ALOAD 2
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 3
ALOAD 3
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L7
ALOAD 2
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L8

結論

由於for-each循環和迭代器在效率方面表現基本相同,這通常是偏好問題。對於大多數場景,for-each 循環由於其簡潔性而在美觀上受到青睞。

以上是For-Each 迴圈與迭代器:哪一個對於遍歷集合更有效?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn