確定效率: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中文網其他相關文章!