[解決済み] Javaでリストを反復処理する方法
質問
Java言語の初心者なので、リスト(または他のコレクション)を反復処理するすべての方法(または少なくとも病的でない方法)と、それぞれの利点または欠点に慣れようとしています。
ある
List<E> list
オブジェクトのすべての要素をループする方法として、私は以下の方法を知っています。
基本的な
に対して
ループ
(もちろん、同等の
while
/
do while
ループも同様)
// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
E element = list.get(i);
// 1 - can call methods of element
// 2 - can use 'i' to make index-based calls to methods of list
// ...
}
注意:@amarseillan が指摘したように、この形式はあまり良い選択ではありません。
を反復するために
List
の実際の実装は
は
get
メソッドを使用する場合ほど効率的でない可能性があります。
Iterator
.
例えば
LinkedList
の実装は、すべての
i番目の要素を得るためにiの前にある要素。
上の例では
List
の実装は
将来の繰り返しをより効率的にするために、その場所を保存しておく必要があります。
そのため
ArrayList
の複雑さとコストは非常に低いので、あまり重要ではありません。
get
は定数時間(O(1))であるのに対して
LinkedList
は、リストのサイズに比例する(O(n))。
の計算量の詳細については、組み込みの
Collections
の実装は、以下を参照してください。
この質問
.
強化された ループ用 (うまく説明されています この質問で )
for (E element : list) {
// 1 - can call methods of element
// ...
}
イテレータ
for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// ...
}
リストイテレータ
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
機能的なJava
list.stream().map(e -> e + 1); // Can apply a transformation function for e
Iterable.forEach , ストリーム.forEach , ...
(Java 8 の Stream API の map メソッド (@i_am_zero さんの回答参照) 。)
を実装したJava 8のコレクションクラスでは
Iterable
(例えば、すべての
List
が追加されました。
forEach
メソッドの代わりに使用することができます。
for ループステートメント
を実証しました。(以下は
別の質問
は、良い比較を提供しています)。
Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - can call methods of an element
// 2 - would need reference to containing object to remove an item
// (TODO: someone please confirm / deny this)
// 3 - functionally separates iteration from the action
// being performed with each item.
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Same capabilities as above plus potentially greater
// utilization of parallelism
// (caution: consequently, order of execution is not guaranteed,
// see [Stream.forEachOrdered][stream-foreach-ordered] for more
// information about this).
他に方法があるとすれば、どのようなものがありますか?
(ちなみに、私の興味は、以下のような願望から来るものでは全くありません。 パフォーマンスの最適化 開発者としてどんなフォームがあるのか知りたいだけなんです)
どのように解決するのですか?
ループの3つの形態は、ほぼ同じです。強化された
for
のループになります。
for (E element : list) {
. . .
}
は
Java言語仕様
,
同一
でのイテレータの明示的な使用と実質的に同じです。
for
ループを使用します。3番目のケースでは、リストの内容を変更するには、現在の要素を削除する必要があります。
remove
というメソッドがあります。インデックスベースのイテレータでは、どのような方法でリストを変更してもかまいません。しかし、現在のインデックスより前にある要素を追加したり削除したりすると、ループが要素を読み飛ばしたり、同じ要素を何度も処理したりする危険性があります。そのような変更をするときは、ループのインデックスを適切に調整する必要があります。
すべての場合において
element
は実際のリスト要素への参照です。どの反復処理メソッドも、リスト内の何かのコピーを作成することはありません。の内部状態への変更は
element
は、常にリスト上の対応する要素の内部状態を見ることができます。
基本的に、リストを反復処理する方法は、インデックスを使用する方法とイテレータを使用する方法の2つだけです。拡張されたforループは、明示的にイテレータを定義する退屈さを避けるためにJava 5で導入された構文的なショートカットに過ぎません。どちらの方法でも、基本的には
for
,
while
または
do while
のブロックがありますが、どれも同じこと(というか、2つのこと)に帰結します。
EDIT: @iX3 がコメントで指摘しているように、このような場合は
ListIterator
を使用して、反復処理中にリストの現在の要素を設定することができます。そのためには
List#listIterator()
ではなく
List#iterator()
を使用してループ変数を初期化します (当然ながら、ループ変数には
ListIterator
ではなく
Iterator
).
関連
-
springboot project MIMEタイプ text/htmlで転送された静的ファイルを読み込む。
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
javaの模造品QQ WeChatのチャットルーム
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 4 at text.Division.main(Divisi
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] 辞書を繰り返し使用するには?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
Java Exceptionが発生しました エラー解決
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
HttpClientがGZIP形式でない場合の対処法
-
JSPで「リストが型解決できない!」の解決方法
-
テストが見つかりませんでした