効率の決定: For-Each ループとイテレータ
コレクションを効率的に走査する際に、どのアプローチが優れているのかという疑問が生じます。 for-each ループまたはiterator?
従来の For ループ
一般に「C スタイル」ループと呼ばれる従来の for ループは、次の構文を例にします:
for(int i=0; i<list.size(); i++) { Object o = list.get(i); }
それぞれについてLoop
Java 5 では、ループ処理を効率化する拡張された for-each ループ構文が導入されました。
for (Integer integer : a) { integer.toString(); }
Iterator
Javaイテレータの抽象化は、 collection:
for (Iterator iterator = a.iterator(); iterator.hasNext();) { Integer integer = (Integer) iterator.next(); integer.toString(); }
パフォーマンスの違い
コレクションから値を変更せずに読み取るだけの場合、for-each ループとイテレータのどちらを選択してもパフォーマンスは大きく変わりません。違い。どちらのアプローチも内部的にイテレータを利用します。
ただし、特定のデータ構造を走査する場合、従来の for ループは for-each ループやイテレータよりも効率が劣る可能性があります。たとえば、リンク リストでは、get(i) を使用して要素を取得するために O(n) 操作が必要です。これにより、ループの複雑さは O(n2) になります。イテレーターは進行するための O(1) 操作を保証し、ループの複雑さは O(n) になります。
バイトコードの比較
両方のループから生成されたバイトコードの比較型はそれらの同等性を示しています:
For-Each Loopバイトコード:
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 中国語 Web サイトの他の関連記事を参照してください。