ネストされたループから抜け出す

1. 概要

このチュートリアルでは、ループ内でlink:/java-continue-and-break[_break_]を使用するさまざまな方法を示すいくつかの例を作成します。 次に、使用しないでループを終了する方法についても説明します。

2. 問題

ネストされたループは、たとえばリストのリストを検索する場合に非常に便利です。
1つの例は、学生のリストです。各学生には、計画されたコースのリストがあります。 _course 0_を計画した1人の名前を検索するとします。
最初に、学生のリストをループします。 次に、そのループ内で、予定されているコースのリストをループします。
学生とコースの名前を印刷すると、次の結果が得られます。
student 0
  course 0
  course 1
student 1
  course 0
  course 1
_course 0_を計画した最初の学生を探していました。 ただし、ループのみを使用する場合、アプリケーションはコースが見つかった後も検索を続けます。
特定のコースを計画した人を見つけたら、*検索を停止します*。検索を続行するには、余分な情報は必要ありませんが、より多くの時間とリソースが必要になります。 *そのため、ネストされたループから抜け出したい*。

3. ブレーク

ネストされたループから出る最初のオプションは、単に_break_ステートメントを使用することです。
String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break;
        }
    }
}
return result;
外側のループと内側のループがあり、両方のループに2つの繰り返しがあります。 内側のループのカウンターが0に等しい場合、_break_コマンドを実行します。 この例を実行すると、次の結果が表示されます。
outer0inner0outer1inner0
または、コードを調整して少し読みやすくすることもできます。
outer 0
  inner 0
outer 1
  inner 0
これは私たちが望むものですか?
ほとんどの場合、*内側のループはbreakステートメントで終了します* * 0が見つかった後。 ただし、外側のループは継続します*。 答えが得られたらすぐに処理を完全に停止したいと思います。

4. ラベル付きブレーク

前の例は正しい方向への一歩でしたが、少し改善する必要があります。 _labeled break_を使用してこれを行うことができます。
String result = "";
myBreakLabel:
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break myBreakLabel;
        }
    }
}
return result;
  • labeled breakは、内側のループだけでなく外側のループを終了します。 この例を実行すると、次の結果が得られます。

outer0inner0
いくつかの書式設定を使用すると、少し読みやすくなります。
outer 0
  inner 0
結果を見ると、*内側のループと外側のループの両方が終了している*ことがわかります。これが達成したいことです。

5. 戻る

別の方法として、_return_ステートメントを使用して、見つかった結果を直接返すこともできます。
String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            return result;
        }
    }
}
return "failed";
ラベルが削除され、_break_ステートメントが_return_ステートメントに置き換えられます。
**上記のコードを実行すると、ラベル付きブレークと同じ結果が得られます。 **この戦略が機能するためには、通常、ループのブロックを独自のメソッドに移動する必要があることに注意してください。

6. 結論

そのため、検索対象のアイテムが見つかった場合など、ループを早期に終了する必要がある場合の対処方法を検討しました。 _break_キーワードは単一ループに役立ち、ネストされたループにはラベル付き__break__sを使用できます。
*代わりに、_return_ステートメントを使用することもできます。* returnを使用すると、ラベルなしブレークとラベル付きブレークの違いを考慮する必要がないため、コードが読みやすくなり、エラーが発生しにくくなります。
コードhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-lang-syntax[GitHubで]をご覧ください。