For Each ループとイテレータ: コレクション トラバーサルの効率
概要
トラバース時Java のコレクションの場合、for-each ループを使用するか、イテレーター。この記事では、これら 2 つのアプローチの効率の違いについて説明します。
For-Each ループ
Java 5 で導入された for-each ループ (拡張 for とも呼ばれます) LOOP) は、コレクションを反復処理するための簡潔で読みやすい構文です。
List<Integer> a = new ArrayList<>(); for (Integer integer : a) { integer.toString(); }
Iterator
イテレータは、コレクションを反復処理するための標準化されたインターフェイスを提供します。これにより、トラバーサル プロセスのカスタム制御が可能になります。
List<Integer> a = new ArrayList<>(); for (Iterator<Integer> iterator = a.iterator(); iterator.hasNext();) { Integer integer = iterator.next(); integer.toString(); }
効率の比較
コレクションへの単純な読み取り専用アクセスの場合、実質的にパフォーマンスの違いはありません。 for-each ループと反復子のアプローチ。 for-each ループは内部的にイテレータ メカニズムを使用します。
ただし、get(i) で従来の「C スタイル」ループを使用する場合は、
for (int i = 0; i < list.size(); i++) { Object o = list.get(i); }
イテレータ アプローチ (両方とも-各ループと明示的なイテレータ) は、特定のデータ構造では大幅に効率的になる可能性があります。たとえば、リンク リストでは、get(i) は O(n) 操作です。イテレータの O(1) next() 操作を使用すると、ループは O(n) 時間で実行されますが、get(i) ループは O(n2) 時間で実行されます。
バイトコードの比較
for-each ループが反復子メカニズムを使用していることを確認するには、両方のアプローチで生成されるバイトコード:
For-Each Loop
List<Integer> a = new ArrayList<>(); for (Integer integer : a) { integer.toString(); }
ALOAD 1 INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator; ASTORE 3 ...
Iterator
List<Integer> a = new ArrayList<>(); for (Iterator<Integer> iterator = a.iterator(); iterator.hasNext();) { Integer integer = iterator.next(); integer.toString(); }
ALOAD 1 INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator; ASTORE 2 ...
ご覧のとおり、生成されたバイトコードは同一であり、パフォーマンス上のペナルティがないことを示しています。
結論
要約すると、読み取り専用アクセスでコレクションを走査する場合、for-each ループと反復子の違いは最小限です。 。イテレータは、特定のデータ構造を操作する場合、またはカスタムの反復動作が必要な場合にのみ利点をもたらします。単純さと読みやすさを考慮すると、一般的には for-each ループが推奨されます。
以上がJava でのコレクション走査に For-Each ループを使用する場合とイテレータを使用する場合にパフォーマンスの違いはありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。