33

コレクションを反復処理し、条件に基づいて何かを行う 4 つの foreach ループがあります。

ここに私が今書いているコードがあります:

boolean breakFlag = false;
String valueFromObj2 = null;
String valueFromObj4 = null;
for(Object1 object1: objects){
  for(Object2 object2: object1){
    // I get some value from object2
    valueFromObj2 = object2.getSomeValue();
    for(Object3 object3 : object2){
      for(Object4 object4: object3){
       // Finally I get some value from Object4.
       valueFromObj4 = object4.getSomeValue();
       // Compare with valueFromObj2 to decide either to break all the foreach loop
       breakFlag = compareTwoVariable(valueFromObj2, valueFromObj4 );
       if(breakFlag){break;}
      } // fourth loop ends here
      if(breakFlag){break;}
    } // third loop ends here
    if(breakFlag){break;}
  } // second loop ends here
  if(breakFlag){break;}
} // first loop ends here

メイン オブジェクト (コード内のオブジェクト) はサードパーティ プロバイダーの SDK から取得されるため、その部分を変更することはできません。4 つの foreach ループすべてを中断するためのより良い方法があるかどうか、スタック オーバーフロー コミュニティに尋ねたいと思います。または、このコードをリファクタリングして読みやすく保守しやすくする他の方法がある場合。

4

9 に答える 9

81

break最も外側のループにラベルを使用し、すべてのループから飛び出したい場合は、このラベルをステートメントに含めます。以下の例では、 label を使用するようにコードを変更しましたOUTERMOST

String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
  for(Object2 object2: object1){
    //I get some value from object2
    valueFromObj2 = object2.getSomeValue();
    for(Object3 object3 : object2){
      for(Object4 object4: object3){
        //Finally I get some value from Object4.
        valueFromObj4 = object4.getSomeValue();
        //Compare with valueFromObj2 to decide either to break all the foreach loop
        if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
          break OUTERMOST;
        }
      }//fourth loop ends here
    }//third loop ends here
  }//second loop ends here
}//first loop ends here
于 2009-02-15T21:06:39.163 に答える
20

すべてのループを関数に抽出し、return を使用します。

于 2009-02-15T21:06:20.083 に答える
6

ラベル付きの break ステートメントを使用できます。この種類のブレークは外側のステートメントを終了します

breakステートメントを参照してください

于 2009-02-15T21:09:13.557 に答える
2

あなたの例はかなり一般的であるため、何が起こっているのかを言うのは難しいですが、提供されたコードから非常に強いコードの匂いがするので、完全に別の方法で行う必要があると考えざるを得ません。実際のデータ構造をより意味のあるものにリファクタリングします。

どんなリストobjectsですか?他にどのような (最も重要な)データが含まれていますか? それほど手間がかからない場合は、より適切なコードを提供していただければ幸いです。私のリファクタラーは、ループの山を見るだけで目がくらむようになっているからです。

于 2009-02-16T06:55:09.170 に答える
2

ラベルを使用する最も簡単な方法については、分岐ステートメント Java チュートリアルを参照してください。for ループの一部またはすべてにラベルを付けて、それらのラベルと組み合わせてbreakorを使用できます。continue

ラベルを使用するreturn代わりに、代わりに使用することもできます。コードをメソッド呼び出しにリファクタリングするだけで、ラベルを使用する必要がまったくなくなります。

于 2009-02-15T21:31:35.157 に答える
1

複数のステートメント (実際にはスタック フレーム) を中断または折りたたむ 1 つの方法は、例外をスローすることですが、これはお勧めできません。 (これを覚えておいてください)。

それ以外の場合は、コードを書き直して、ループから抜け出すことをお勧めします。このコードを他の方法で変更できない場合は、例外が発生する必要があります...

于 2009-02-15T21:05:31.320 に答える
0

Java がラベル付きブレークをサポートしているという事実とは別に、終了条件に達した場合、C++ で時間前に終了することは可能ですか?も参照してください。これは、他の関連するソリューションと同様の質問です。

于 2009-02-15T21:20:41.267 に答える
0

例外をスローして、ループの外でキャッチしますか? 「有害と見なされる」ものを使用しますか?

コンピューター サイエンスが窮地に立たされるのは、ちょっとおかしな話です ;-)

于 2009-02-15T21:04:16.283 に答える
0

簡単な解決策は、検索プロセス全体をメソッドに入れreturn、答えが得られたらすぐにすることです。

ただし、サンプル コードの抽象的な形式では、他の可能性が疑問視されています。たとえば、Map総当たりループを使用する必要がないように、コンテンツの一部を「インデックス化」する方法 (インスタンスを使用するなど) はありますか?

于 2009-02-15T21:10:18.530 に答える