15

Object の Iterator を使用するときは、while ループを使用します(Java を学習するすべての本に書かれているように、Bruce Eckel のJava での思考のように):

Iterator it=...

while(it.hasNext()){
    //...
}

しかし、代わりに誰かがfor ループを使用するのを見たことがあります:

Iterator it=...
for (Iterator it=...; it.hasNext();){
    //...
}

この選択がわかりません:

  • 序数シーケンス (配列として) またはステップの特別なルール (通常は単純なインクリメントとして宣言) を持つコレクションがある場合は、 for ループを使用しますcounter++
  • I have'nt this Constraint but only a logic condition for exit でループが終了したときに、while ループを使用します。

それは、他の原因のないスタイルコーディングの問題ですか、それとも私が知らない他のロジック (パフォーマンスなど) が存在するのでしょうか?

フィードバックをお寄せいただきありがとうございます

4

5 に答える 5

32

for ループの正しい構文は次のとおりです。

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(コード内の前の宣言は余分であり、for ループの見出しにある余分なセミコロンも不要です。)

この構文を使用するかwhileループを使用するかは好みの問題ですが、どちらもまったく同じに変換されます。for ループの一般的な構文は次のとおりです。

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

これは次と同等です:

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

編集:実際には、(質問のように) 変数が init ステートメントで宣言されている場合、上記の 2 つの形式は完全に同等ではありません。この場合、イテレータ変数のスコープに違いがあります。for ループの場合、スコープはループ自体に限定されますが、while ループの場合、スコープは外側のブロックの最後まで拡張されます (宣言はループの外にあるため、大きな驚きはありません)。

また、他の人が指摘しているように、Java の新しいバージョンでは、for ループの簡略表記があります。

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

次のように記述できます。

for (Foo foo : myIterable) {
    //...
}

この形式では、もちろん反復子への直接参照が失われます。これは、反復中にコレクションから項目を削除する場合などに必要です。

于 2009-02-05T11:54:20.230 に答える
9

それは単なるスタイルの問題であり、あなたのように、インデックスで何かを使用する場合は for ループを好みます。Java 5 を使用している場合は、もちろんコレクションに対して foreach ループを使用する必要があります。

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}
于 2009-02-05T11:54:19.790 に答える
9

Iteratorfor ループ内で を宣言する目的は、変数のスコープを最小限に抑えることです。これは良い方法です。

ループの外側を宣言するIteratorと、ループが完了した後も参照は有効/有効です。99.99% の確率で、ループが完了したら を使い続ける必要はないIteratorため、このようなスタイルは次のようなバグにつながる可能性があります。

//iterate over first collection
Iterator it1 = collection1.iterator();
while(it1.hasNext()) {
   //blah blah
}

//iterate over second collection
Iterator it2 = collection2.iterator();
while(it1.hasNext()) {
   //oops copy and paste error! it1 has no more elements at this point
}
于 2009-02-05T14:40:34.700 に答える
4

it最初の方法がループ後の値を記憶すること以外は、これら 2 つの方法に大きな違いはありません。2 番目の方法では、ループ内で変数を再宣言するため、おそらくエラーがスローされます。

実は、これには 3 つ目の方法もあります。例えば書く代わりに

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

あなたはほとんどの場合書くことができます

for (SomeObject so: foo) {...}

これら2つは同じものに等しい...

于 2009-02-05T11:57:19.550 に答える
2

明示的な (「古いスタイル」の) for ループを使用するのは、単純に単純に、新しい構文にまだ慣れていないためです (私は個人的には、よりクリーンだと思います)。

より長い for ループ構成の実際の具体的な利点の 1 つは、反復子への参照があるため、それ以外のメソッドを呼び出すことができることnext()です。特に、hasNext()呼び出すと便利なことがよくあります - コンマ区切りの文字列のリストを出力したい場合を想像してください:

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

より冗長な for ループを使用する場合、このように「これが最後」のケースを区別するだけです。

于 2009-02-05T11:56:57.447 に答える