Ich habe ein verschachteltes Schleifenkonstrukt wie folgt:
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break; // Breaks out of the inner loop
}
}
}
Wie kann ich nun aus beiden Schleifen ausbrechen? Ich habe mir ähnliche Fragen angeschaut, aber keine betrifft Java. Ich konnte diese Lösungen nicht anwenden, da die meisten gotischen Methoden verwendet wurden.
Ich möchte die innere Schleife nicht auf eine andere Weise einsetzen.
Ich möchte die Schleifen nicht wiederholen. Beim Brechen bin ich mit der Ausführung des Schleifenblocks fertig.
Wie andere Antworter würde ich definitiv lieber die Loops auf eine andere Art und Weise verwenden, an dem Punkt, an dem Sie einfach zurückkehren können, um die Iteration vollständig zu beenden. Diese Antwort zeigt nur, wie die Anforderungen in der Frage erfüllt werden können.
Sie können break
mit einem Label für die äußere Schleife verwenden. Zum Beispiel:
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
Dies druckt:
0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done
Technisch ist die richtige Antwort, die äußere Schleife zu kennzeichnen. Wenn Sie in der Praxis an einer beliebigen Stelle innerhalb einer inneren Schleife abbrechen möchten, sollten Sie den Code besser in eine Methode (eine statische Methode, wenn nötig) externalisieren und dann aufrufen.
Das würde sich für die Lesbarkeit rechnen.
Der Code würde in etwa so aussehen:
private static String search(...)
{
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
return search;
}
}
}
return null;
}
Das Beispiel für die akzeptierte Antwort abgleichen:
public class Test {
public static void main(String[] args) {
loop();
System.out.println("Done");
}
public static void loop() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
return;
}
System.out.println(i + " " + j);
}
}
}
}
Sie können einen benannten Block für die Schleifen verwenden:
search: {
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break search;
}
}
}
}
Ich benutze niemals Etiketten. Es scheint eine schlechte Praxis zu sein. Folgendes würde ich tun:
boolean finished = false;
for (int i = 0; i < 5 && !finished; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
finished = true;
break;
}
}
}
Sie können Etiketten verwenden:
label1:
for (int i = 0;;) {
for (int g = 0;;) {
break label1;
}
}
Verwenden Sie eine Funktion:
public void doSomething(List<Type> types, List<Type> types2){
for(Type t1 : types){
for (Type t : types2) {
if (some condition) {
// Do something and return...
return;
}
}
}
}
Sie können eine temporäre Variable verwenden:
boolean outerBreak = false;
for (Type type : types) {
if(outerBreak) break;
for (Type t : types2) {
if (some condition) {
// Do something and break...
outerBreak = true;
break; // Breaks out of the inner loop
}
}
}
Abhängig von Ihrer Funktion können Sie auch die innere Schleife verlassen oder zurückkehren:
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
return;
}
}
}
Wenn Sie break
s und goto
s nicht mögen, können Sie anstelle des For-In eine "traditionelle" for-Schleife mit einer zusätzlichen Abbruchbedingung verwenden:
int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
for (b = 0; b < 10 && !abort; b++) {
if (condition) {
doSomeThing();
abort = true;
}
}
}
Ich musste etwas Ähnliches tun, entschied mich jedoch dafür, die erweiterte for-Schleife nicht zu verwenden.
int s = type.size();
for (int i = 0; i < s; i++) {
for (int j = 0; j < t.size(); j++) {
if (condition) {
// do stuff after which you want
// to completely break out of both loops
s = 0; // enables the _main_ loop to terminate
break;
}
}
}
Ich bevorzuge es, den Schleifentests ein explizites "Exit" hinzuzufügen. Es macht jedem zufälligen Leser klar, dass die Schleife vorzeitig beendet werden kann.
boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}
Java 8 Stream
Lösung:
List<Type> types1 = ...
List<Type> types2 = ...
types1.stream()
.flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
.filter(types -> /**some condition**/)
.findFirst()
.ifPresent(types -> /**do something**/);
Sie können aus allen Schleifen ausbrechen, ohne ein Label oder Flag zu verwenden.
Es ist nur eine knifflige Lösung.
Hier ist Bedingung1 die Bedingung, die verwendet wird, um aus den Schleifen K und J zu springen .. und Bedingung2 ist die Bedingung, die verwendet wird, um aus der Schleife K, J und I zu brechen.
Zum Beispiel:
public class BreakTesting {
public static void main(String[] args) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = 0; k < 9; k++) {
if (condition1) {
System.out.println("Breaking from Loop K and J");
k = 9;
j = 9;
}
if (condition2) {
System.out.println("Breaking from Loop K, J and I");
k = 9;
j = 9;
i = 9;
}
}
}
}
System.out.println("End of I , J , K");
}
}
Normalerweise kommt in solchen Fällen eine sinnvollere Logik in Betracht. Nehmen wir an, einige der iterierten 'for'-Objekte werden gesucht oder manipuliert, daher verwende ich normalerweise den funktionalen Ansatz:
public Object searching(Object[] types) { // Or manipulating
List<Object> typesReferences = new ArrayList<Object>();
List<Object> typesReferences2 = new ArrayList<Object>();
for (Object type : typesReferences) {
Object o = getByCriterion(typesReferences2, type);
if(o != null) return o;
}
return null;
}
private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
for (Object typeReference : typesReferences2) {
if(typeReference.equals(criterion)) {
// here comes other complex or specific logic || typeReference.equals(new Object())
return typeReference;
}
}
return null;
}
Haupt Nachteile:
Die Profis:
Es handelt sich also lediglich um eine andere Vorgehensweise.
Im Grunde eine Frage an den Autor dieser Frage: Was halten Sie von diesem Ansatz?
Beste und einfache Methode ..
outerloop:
for(int i=0; i<10; i++){
// here we can break Outer loop by
break outerloop;
innerloop:
for(int i=0; i<10; i++){
// here we can break innerloop by
break innerloop;
}
}
Wenn es in einer Funktion ist, warum geben Sie es nicht einfach zurück:
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
return value;
}
}
}
Eher ungewöhnlicher Ansatz, aber in Bezug auf die Codelänge ( nicht die Leistung ) ist dies das Einfachste, was Sie tun können:
for(int i = 0; i++; i < j) {
if(wanna exit) {
i = i + j; // if more nested, also add the
// maximum value for the other loops
}
}
Verwenden Sie Etiketten.
INNER:for(int j = 0; j < numbers.length; j++) {
System.out.println("Even number: " + i + ", break from INNER label");
break INNER;
}
Siehe diesen Artikel
Eine andere Lösung, die ohne Beispiel erwähnt wurde (sie funktioniert tatsächlich im Prod-Code).
try {
for (Type type : types) {
for (Type t : types2) {
if (some condition #1) {
// Do something and break the loop.
throw new BreakLoopException();
}
}
}
}
catch (BreakLoopException e) {
// Do something on look breaking.
}
Natürlich sollte BreakLoopException
intern, privat und mit No-Stack-Trace beschleunigt sein:
private static class BreakLoopException extends Exception {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[0];
}
}
Demo für break
, continue
und label
:
Die Java-Schlüsselwörter break
und continue
haben einen Standardwert. Es ist die "nächste Schleife", und heute, nach ein paar Jahren der Verwendung von Java, habe ich es einfach verstanden!
Es scheint selten, aber nützlich zu sein.
import org.junit.Test;
/**
* Created by cui on 17-5-4.
*/
public class BranchLabel {
@Test
public void test() {
System.out.println("testBreak");
testBreak();
System.out.println("testBreakLabel");
testBreakLabel();
System.out.println("testContinue");
testContinue();
System.out.println("testContinueLabel");
testContinueLabel();
}
/**
testBreak
a=0,b=0
a=0,b=1
a=1,b=0
a=1,b=1
a=2,b=0
a=2,b=1
a=3,b=0
a=3,b=1
a=4,b=0
a=4,b=1
*/
public void testBreak() {
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
if (b == 2) {
break;
}
System.out.println("a=" + a + ",b=" + b);
}
}
}
/**
testContinue
a=0,b=0
a=0,b=1
a=0,b=3
a=0,b=4
a=1,b=0
a=1,b=1
a=1,b=3
a=1,b=4
a=2,b=0
a=2,b=1
a=2,b=3
a=2,b=4
a=3,b=0
a=3,b=1
a=3,b=3
a=3,b=4
a=4,b=0
a=4,b=1
a=4,b=3
a=4,b=4
*/
public void testContinue() {
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
if (b == 2) {
continue;
}
System.out.println("a=" + a + ",b=" + b);
}
}
}
/**
testBreakLabel
a=0,b=0,c=0
a=0,b=0,c=1
* */
public void testBreakLabel() {
anyName:
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
for (int c = 0; c < 5; c++) {
if (c == 2) {
break anyName;
}
System.out.println("a=" + a + ",b=" + b + ",c=" + c);
}
}
}
}
/**
testContinueLabel
a=0,b=0,c=0
a=0,b=0,c=1
a=1,b=0,c=0
a=1,b=0,c=1
a=2,b=0,c=0
a=2,b=0,c=1
a=3,b=0,c=0
a=3,b=0,c=1
a=4,b=0,c=0
a=4,b=0,c=1
*/
public void testContinueLabel() {
anyName:
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
for (int c = 0; c < 5; c++) {
if (c == 2) {
continue anyName;
}
System.out.println("a=" + a + ",b=" + b + ",c=" + c);
}
}
}
}
}
for (int j = 0; j < 5; j++) //inner loop
sollte durch for (int j = 0; j < 5 && !exitloops; j++)
ersetzt werden.
In diesem Fall sollten vollständige verschachtelte Schleifen beendet werden, wenn die Bedingung True
lautet. Aber wenn wir exitloops
nur zum oberen loop
verwenden
for (int i = 0; i < 5 && !exitloops; i++) //upper loop
Dann wird die innere Schleife fortgesetzt, da es kein zusätzliches Flag gibt, das diese innere Schleife zum Verlassen benachrichtigt.
Beispiel: Wenn
i = 3
Undj=2
, Lautet die Bedingungfalse
. Aber in der nächsten Iteration der inneren Schleifej=3
Wird die Bedingung(i*j)
Zu9
, Dietrue
ist, aber die innere Schleife wird fortgesetzt, bisj
wird5
.
Also muss es exitloops
auch für die inneren Schleifen verwenden.
boolean exitloops = false;
for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true.
for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement.
if (i * j > 6) {
exitloops = true;
System.out.println("Inner loop still Continues For i * j is => "+i*j);
break;
}
System.out.println(i*j);
}
}
Verwenden Sie wie beim Vorschlag von @ 1800 INFORMATION die Bedingung, die die innere Schleife als Bedingung der äußeren Schleife unterbricht:
boolean hasAccess = false;
for (int i = 0; i < x && hasAccess == false; i++){
for (int j = 0; j < y; j++){
if (condition == true){
hasAccess = true;
break;
}
}
}
boolean broken = false; // declared outside of the loop for efficiency
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
broken = true;
break;
}
}
if (broken) {
break;
}
}
Wenn es sich um eine neue Implementierung handelt, können Sie versuchen, die Logik als if-else_if-else-Anweisungen umzuschreiben.
while(keep_going) {
if(keep_going && condition_one_holds) {
// Code
}
if(keep_going && condition_two_holds) {
// Code
}
if(keep_going && condition_three_holds) {
// Code
}
if(keep_going && something_goes_really_bad) {
keep_going=false;
}
if(keep_going && condition_four_holds) {
// Code
}
if(keep_going && condition_five_holds) {
// Code
}
}
Andernfalls können Sie versuchen, ein Flag zu setzen, wenn diese spezielle Bedingung aufgetreten ist, und überprüfen, ob dieses Flag in jeder Ihrer Schleifenbedingungen vorhanden ist.
something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
// Code, things happen
while(something else && !something_bad_has_happened){
// Lots of code, things happens
if(something happened){
-> Then control should be returned ->
something_bad_has_happened=true;
continue;
}
}
if(something_bad_has_happened) { // The things below will not be executed
continue;
}
// Other things may happen here as well, but they will not be executed
// once control is returned from the inner cycle.
}
HIER! Eine einfache Pause funktioniert zwar nicht, kann aber mit continue
ausgeführt werden.
Wenn Sie die Logik einfach von einer Programmiersprache nach Java portieren und die Sache zum Laufen bringen wollen, können Sie versuchen, labels zu verwenden.
Labeled break concept wird verwendet, um verschachtelte Schleifen in Java aufzubrechen. Durch die Verwendung von Labeled break können Sie die Verschachtelung von Schleifen an einer beliebigen Position aufheben. Beispiel 1:
loop1:
for(int i= 0; i<6; i++){
for(int j=0; j<5; j++){
if(i==3)
break loop1;
}
}
angenommen, es gibt 3 Schleifen und Sie möchten die Schleife 3 beenden: Beispiel 2:
loop3:
for(int i= 0; i<6; i++){
loop2:
for(int k= 0; k<6; k++){
loop1:
for(int j=0; j<5; j++){
if(i==3)
break loop3;
}
}
}
Demo
public static void main(String[] args) {
outer:
while (true) {
while (true) {
break outer;
}
}
}
Sie können Folgendes tun:
setze eine lokale Variable auf false
setzen Sie diese Variable true
in der ersten Schleife, wenn Sie brechen möchten
dann kannst du in der äußeren Schleife prüfen, ob die Bedingung dann auch von der äußeren Schleife abgebrochen wird.
boolean isBreakNeeded = false;
for (int i = 0; i < some.length; i++) {
for (int j = 0; j < some.lengthasWell; j++) {
//want to set variable if (){
isBreakNeeded = true;
break;
}
if (isBreakNeeded) {
break; //will make you break from the outer loop as well
}
}
In einigen Fällen können wir hier while
loop effektiv verwenden.
Random Rand = new Random();
// Just an example
for (int k = 0; k < 10; ++k) {
int count = 0;
while (!(Rand.nextInt(200) == 100)) {
count++;
}
results[k] = count;
}
Auch das Erstellen eines Flags für die äußere Schleife und die Überprüfung, dass nach jeder Ausführung der inneren Schleife die Antwort sein kann.
So was:
for (Type type : types) {
boolean flag=false;
for (Type t : types2) {
if (some condition) {
// Do something and break...
flag=true;
break; // Breaks out of the inner loop
}
}
if(flag)
break;
}
Überprüfen Sie, ob die innere Schleife mit einer if-Anweisung verlassen wird, indem Sie die Variable der inneren Schleife überprüfen. Sie können auch eine andere Variable erstellen, z. B. einen Booleschen Wert, um zu überprüfen, ob die innere Schleife beendet wird.
In diesem Beispiel wird anhand der Variablen der inneren Schleife überprüft, ob sie beendet wurde:
int i, j;
for(i = 0; i < 7; i++){
for(j = 0; j < 5; j++) {
if (some condition) {
// Do something and break...
break; // Breaks out of the inner loop
}
}
if(j < 5){ // Checks if inner loop wasn't finished
break; // Breaks out of the outer loop
}
}
Verwenden Sie einfach label, um innere Schleifen zu durchbrechen
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
Unten sehen Sie ein Beispiel, in dem die Anweisung "break" den Cursor aus der for-Schleife drückt, wenn die Bedingung erfüllt ist.
public class Practice3_FindDuplicateNumber {
public static void main(String[] args) {
Integer[] inp = { 2, 3, 4, 3, 3 };
Integer[] aux_arr = new Integer[inp.length];
boolean isduplicate = false;
for (int i = 0; i < aux_arr.length; i++) {
aux_arr[i] = -1;
}
outer: for (int i = 0; i < inp.length; i++) {
if (aux_arr[inp[i]] == -200) {
System.out.println("Duplicate Found at index: " + i + " Carrying value: " + inp[i]);
isduplicate = true;
break outer;
} else {
aux_arr[inp[i]] = -200;
}
}
for (Integer integer : aux_arr) {
System.out.println(integer);
}
if (isduplicate == false) {
System.out.println("No Duplicates!!!!!");
} else {
System.out.println("Duplicates!!!!!");
}
}
}
Java hat keine Goto-Funktion wie in C++. Dennoch ist goto
ein in Java reserviertes Schlüsselwort. Sie könnten es in Zukunft umsetzen. Für Ihre Frage lautet die Antwort, dass es in Java ein so genanntes Label gibt, auf das Sie eine continue
- und break
-Anweisung anwenden können. Den Code finden Sie unten:
public static void main(String ...args) {
outerLoop: for(int i=0;i<10;i++) {
for(int j=10;j>0;j--) {
System.out.println(i+" "+j);
if(i==j) {
System.out.println("Condition Fulfilled");
break outerLoop;
}
}
}
System.out.println("Got out of the outer loop");
}
boolean condition = false;
for (Type type : types) {
for (int i = 0; i < otherTypes.size && !condition; i ++) {
condition = true; // If your condition is satisfied
}
}
Verwenden Sie condition
als Flag, wenn Sie mit der Verarbeitung fertig sind. Dann läuft die innere Schleife nur weiter, wenn die Bedingung nicht erfüllt ist. In jedem Fall bleibt die äußere Schleife auf "chuggin".