私はしばしば次のようなコードを見ます:
Iterator i = list.iterator();
while(i.hasNext()) {
...
}
しかし、私はそれを(Java 1.5が利用できない場合、またはそれぞれに対して使用できない場合))と書く:
for(Iterator i = list.iterator(); i.hasNext(); ) {
...
}
なぜなら
i
をより小さいスコープに保持しますi
はwhile以外で使用されていますか?i
はどこで宣言されていますか?)複雑なことをするために複雑なコードを作成するだけで済むように、コードはできるだけ簡単に理解できる必要があると思います。どう思いますか?どちらが良いですか?
イテレータのスコープをforループだけに設定するため、私はforループを好みます。
While、for、およびforeachコンストラクトには適切な使用法があります。
while
-繰り返し処理を行い、ループの決定要因が条件のみに基づいている場合に使用します。このループ構造では、インデックスを保持することは二次的な関心事にすぎません。すべてが条件に基づいている必要があります
for
-ループしていて、主な関心事が配列/コレクション/リストのインデックスである場合、これを使用します。 all要素をとにかく特定の順序で(たとえば、ソートされたリストを逆方向に)通過する可能性が最も高い場合は、forを使用すると便利です。
foreach
-順序に関係なくコレクションを通過するだけの場合に使用します。
明らかに上記には例外がありますが、それを使用することを決定するときに使用する一般的なルールです。そうは言っても、foreach
をより頻繁に使用する傾向があります。
なぜfor-eachコンストラクトを使用しないのですか? (しばらくの間Javaを使用していませんが、これはC#に存在し、Java 1.5にもこれがあると確信しています):
List<String> names = new ArrayList<String>();
names.add("a");
names.add("b");
names.add("c");
for (String name : names)
System.out.println(name.charAt(0));
あなたが指摘したように、ここでスコープが最大の問題だと思います。
「while」の例では、反復子はループの外側で宣言されているため、ループが終了した後も存在し続けます。これは、同じイテレータが後で使用される場合に問題を引き起こす可能性があります。例別のループで使用する前に初期化するのを忘れることがあります。
「for」の例では、反復子はループ内で宣言されているため、そのスコープはループに制限されます。ループ後に使用しようとすると、コンパイラエラーが発生します。
私見、forループは、英語の観点からこのコードを見た場合、このシナリオでは読みにくくなります。私は著者が悪用するコードに取り組んでいますforループ、それはきれいではありません。以下を比較してください:
for (; (currUserObjectIndex < _domainObjectReferences.Length) && (_domainObjectReferences[currUserObjectIndex].VisualIndex == index); ++currUserObjectIndex)
++currNumUserObjects;
対
while (currUserObjectIndex < _domainObjectReferences.Length && _domainObjectReferences[currUserObjectIndex].VisualIndex == index)
{
++currNumUserObjects;
++currUserObjectIndex;
}
イテレータを一度だけ使用して破棄する場合は、2番目の形式が優先されます。それ以外の場合は、最初のフォームを使用する必要があります
forループを使用すると、現在動作しているforループのみに変数のスコープを設定するため、単一の変数で作業できます。ただし、これはwhileループでは不可能です。例えば:
int i; for(i = 0; in1; i ++)何かをします。
for(i = 0; i n2; i + = 2)何かをします。
したがって、最初のループの後、i = n1-1で終わります。しかし、2番目のループを使用している間、iを再び0に設定できます。ただし
int i = 0;
while(i less limit){何かをする..; i ++; }
したがって、iは最後にlimit-1に設定されます。したがって、同じiを別のwhileループで使用することはできません。
「for」ループは、反復する際により明確で適切であることに同意します。
「while」ループはポーリングに適しています。または、終了条件を満たすループの数は、ループ内のアクティビティに基づいて変化します。
この場合、おそらくそれはおそらく重要ではありませんが、コンパイラ、VM、およびCPUには通常、ループパフォーマンスを向上させるフード内でユーザーが使用する特別な最適化技術があります(そして近い将来に並行して)、一般的にはwhileループ(実際に実行する方法を決定するのが難しいため)。しかし、ほとんどの場合、コードの明快さは最適化よりも優先されます。
どちらでも構いません。私は自分で()を使用していますが、コンパイルの問題があるかどうかわかりません。どちらもほぼ同じものに最適化されていると思います。
どちらも非常に優れていますが、読みやすいため、最初の例を使用する傾向があります。
While()ループを使用すると、各行で実行される操作が少なくなり、コードを初めて使用する人がコードの内容を理解しやすくなります。
また、このタイプの構造により、(メソッドの上部の)共通の場所で初期化をグループ化できます。これにより、コメントが簡単になり、初めて読む人の概念化も容易になります。
両方とも問題ありませんが、イテレータに直接アクセスすると便利な場合があることを覚えておいてください(特定の条件に一致する要素を削除する場合など-for(T o内でcollection.remove(o)を実行するとConcurrentModificationExceptionが発生します)。コレクション)ループ)。
私は自然に読みやすいように見えるので、ほとんど常にfor(blah:blah)[foreach]構文を書くことを好みます。一般的なイテレータの概念には、プログラミング以外の類似点はありません。
Forループは可能な限り使用する必要があることに同意しますが、ループの本体の反復子を制御するより複雑なロジックがある場合があります。その場合は、しばらく一緒に行かなければなりません。
わかりやすくするために、私はforループを使いました。私がwhileループを使用している間、何らかの不確定な条件に直面したとき。
アカデミアは、プログラムに関する複雑な推論を少なくするため、whileループを好む傾向があります。コードを読みやすくするため、for-またはforeach-loop構造を好む傾向があります。