[解決済み】for-eachループとイテレータはどちらが効率的か?
2022-04-10 02:47:15
質問
コレクションをトラバースする最も効率的な方法はどれですか?
List<Integer> a = new ArrayList<Integer>();
for (Integer integer : a) {
integer.toString();
}
または
List<Integer> a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();) {
Integer integer = (Integer) iterator.next();
integer.toString();
}
の完全な複製ではないことに注意してください。
この
,
これ
,
これ
または
この
最後の質問の答えの1つがそれに近いですが。これがダブらない理由は、これらのほとんどは、ループを比較するために
get(i)
イテレータを使うのではなく、ループの中で使うのです。
で提案したように メタ この質問に対する私の回答を掲載します。
解決方法は?
もし、すべての値を読み取るためにコレクションをさまようだけなら、イテレータを使っても新しいループ構文を使っても違いはありません。
しかし、あなたがループを意味する場合、古い "c-style" ループを意味します。
for(int i=0; i<list.size(); i++) {
Object o = list.get(i);
}
そうすると、新しいforループ、つまりイテレータは、基礎となるデータ構造によっては、もっと効率的なものになる可能性があるのです。というのも、あるデータ構造では
get(i)
はO(n)演算であるため、ループはO(n)演算となる。
2
)操作になります。従来のリンクリストは、このようなデータ構造の一例である。すべてのイテレータは、基本的な要件として
next()
はO(1)演算であるべきで、ループはO(n)になる。
新しい for ループ構文によってイテレータが水面下で使用されていることを確認するために、次の 2 つの Java スニペットから生成されたバイトコードを比較してみましょう。まずforループ。
List<Integer> a = new ArrayList<Integer>();
for (Integer integer : a)
{
integer.toString();
}
// Byte code
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
そして2つ目は、イテレータです。
List<Integer> a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();)
{
Integer integer = (Integer) iterator.next();
integer.toString();
}
// Bytecode:
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ループを選ぶと思います。
関連
-
[解決済み] tempとは何ですか、またjavaにおけるtempの用途は何ですか?
-
[解決済み] ボタンでTextFieldをクリアする(Java)
-
[解決済み] 一部の入力ファイルが非推奨のAPIを使用またはオーバーライドしている
-
[解決済み] Maven: assembly-pluginが全く実行されない
-
[解決済み] Javaの「for each」ループはどのように機能するのですか?
-
[解決済み] Javaでenumを繰り返し処理するためのforループ
-
[解決済み] Javaでリストを反復処理する方法
-
[解決済み] JavaScriptのfor...of構文でループのカウンタ/インデックスを取得する
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
-
[解決済み】Javaのfor-eachループで反復カウンタにアクセスする方法はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] java.sql.SQLException: ORA-00933: SQL コマンドが正しく終了していません。
-
[解決済み] この配列の中の数字を入れ替えるには、何が足りないのでしょうか?ジャバ
-
[解決済み] 警告: コンテキスト初期化中に例外が発生 - 更新の試みはキャンセルされました。
-
[解決済み] java.lang.ClassNotFoundException: クラス com.ibm.db2.jcc.DB2Driver が Worklight プラットフォームまたはプロジェクトに見つかりませんでした。
-
[解決済み] eclipseからTomcatに物理的に発行されるmyjspはどこにあるのでしょうか?
-
[解決済み] Eclipseでクラスとそれに対応するファイルの名前を変更する方法は?
-
[解決済み] Maven: assembly-pluginが全く実行されない
-
[解決済み] Javaの「for each」ループはどのように機能するのですか?
-
[解決済み] Javaでリストを反復処理する方法
-
[解決済み】配列のインデックスの代わりにイテレータを使用する理由は?