Kaip išeiti iš nested kilpų Java?

Turiu šį įdėtos kilpos konstrukciją:

 for (Type type : types) { for (Type t : types2) { if (some condition) { // Do something and break... break; // Breaks out of the inner loop } } } 

Dabar, kaip aš galiu išeiti iš abiejų ciklų. Pažvelgiau į panašius klausimus, bet niekas konkrečiai nenurodo „Java“. Aš negalėjau taikyti šių sprendimų, nes dauguma naudojamų gotų.

Aš nenoriu įdėti vidinės kilpos į kitą metodą.

Atnaujinimas: nenoriu iš naujo paleisti ciklų, kai nutrauksiu, baigiau kilpą.

1600 m
20 мая '09 в 12:07 2009-05-20 12:07 „boutta“ yra nustatytas gegužės 20 d ., 09:07, 2009-05-20 12:07
ответ 31 atsakymų
  • 1
  • 2

Kaip ir kiti respondentai, aš tikrai norėčiau, kad ciklai būtų kitaip, o po to jūs galite tiesiog grįžti į visiškai sustabdyti iteraciją. Šis atsakymas tiesiog parodo, kaip galite patenkinti klausimo reikalavimus.

Galite naudoti break su išorinės kilpos etikete. Pavyzdžiui:

 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"); } } 

Jis spausdina:

 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 
2160
20 мая '09 в 12:11 2009-05-20 12:11 Atsakymą davė Jon Skeet gegužės 20 d., 09:11 2009-05-20 12:11

Techniškai teisingas atsakymas - pažymėti išorinę kilpą. Praktiškai, jei norite išeiti iš bet kokio vidinio kontūro taško, geriau įstumti kodą į metodą (jei reikia, statinį metodą), tada paskambinkite.

Tai pateisintų aiškumą.

Kodas bus panašus:

border=0
 private static String search(...) { for (Type type : types) { for (Type t : types2) { if (some condition) { // Do something and break... return search; } } } return null; } 

Susipažinkite su priimtino atsakymo pavyzdžiu:

  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); } } } } 
377
14 нояб. atsakymas pateikiamas Zo72 14 lapkričio. 2011-11-14 21:26 '11, 21:26, 2011-11-14 21:26

Galite naudoti pavadintą bloką aplink kilpas:

 search: { for (Type type : types) { for (Type t : types2) { if (some condition) { // Do something and break... break search; } } } } 
193
20 мая '09 в 12:12 2009-05-20 12:12 atsakė Joey gegužės 20 d., 09:12 2009-05-20 12:12

Aš niekada nenaudoju žymių. Atrodo bloga praktika. Štai ką darysiu:

 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; } } } 
116
07 дек. Atsakymas, pateiktas Elle Mundy, gruodžio 7 d 2011-12-07 20:52 '11 ne 20:52 2011-12-07 20:52

Galite naudoti žymes:

 label1: for (int i = 0;;) { for (int g = 0;;) { break label1; } } 
81
20 мая '09 в 12:11 2009-05-20 12:11 atsakė simon622 gegužės 20 d., 09:11 2009-05-20 12:11

gal su funkcija?

 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; } } } } 
32
20 мая '09 в 14:43 2009-05-20 14:43 atsakymą pateikė „ Fortega“ gegužės 20 d., 09:43 , 2009-05-20 14:43

Galite naudoti laikiną kintamąjį:

 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 } } } 

Priklausomai nuo jūsų funkcijos, galite išeiti iš vidinės kilpos ir grįžti iš jos:

 for (Type type : types) { for (Type t : types2) { if (some condition) { // Do something and break... return; } } } 
15
20 мая '09 в 12:11 2009-05-20 12:11 atsakė Miguel Ping gegužės 20 d., 09:11 2009-05-20 12:11

Jei jums nepatinka break ir „ goto , galite naudoti „tradicinį“ kilpui vietoj „in-in“ su papildoma pertraukos sąlyga:

 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; } } } 
10
22 дек. Atsakymas duotas 22 d. 2013-12-22 01:56 '13 ne 1:56 2013-12-22 01:56

Aš turėjau daryti tą patį, bet nusprendžiau nenaudoti išplėstinės linijos.

 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; } } } 
9
05 февр. Atsakymą pateikė Swifty McSwifterton 05 vasaris. 2012-02-05 09:04 '12 at 9:04 2012-02-05 09:04

Norėčiau pridėti aiškų „išėjimą“ į „loop“ testus. Tai leidžia bet kokiam atsitiktiniam skaitytuvui suprasti, kad ciklas gali baigtis anksčiau.

 boolean earlyExit = false; for(int i = 0 ; i < 10  !earlyExit; i++) { for(int j = 0 ; i < 10  !earlyExit; j++) { earlyExit = true; } } 
7
04 авг. atsakymą pateikė ddyer 04 rug . 2014-08-04 20:29 '14, 20:29, 2014-08-04 20:29

„Java 8 Stream sprendimas:

 List<Type> types1 = ... List<Type> types2 = ... types1.stream() .flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2})) .filter(types -> ) .findFirst() .ifPresent(types -> ); 
5
16 июля '17 в 13:24 2017-07-16 13:24 Atsakymą pateikė Igoris Rybak , liepos 16 d. 17, 13:24 2017-07-16 13:24

Greičiau aš ilgą laiką galvojau, kaip šį klausimą atsakyti į šį klausimą.

Paprastai tokie atvejai yra įtraukiami į prasmingesnės logikos sritį, pvz., Kai kurias pakartotines nagrinėjamų objektų paieškas arba manipuliavimą, todėl paprastai naudojasi funkciniu požiūriu:

 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; } 

Pagrindiniai trūkumai:

  • maždaug dvigubai daugiau linijų
  • daugiau skaičiavimo ciklų suvartojimo, o tai reiškia, kad jis yra lėtesnis iš algoritminio
  • daugiau teksto įvedimo

Argumentai "už":

  • Didesnė reikšmė problemų atskyrimui dėl funkcinės detalės
  • didesnė pakartotinio naudojimo norma ir kontrolė nustato / valdo logiką be
  • metodai yra trumpalaikiai, todėl jie yra kompaktiškesni ir aiškesni
  • subjektyviai didesnis skaitymo koeficientas

Taigi, ji tik tvarko bylą naudodama kitokį požiūrį.

Iš esmės klausimas šio klausimo autoriui: ką manote apie šį požiūrį?

4
28 янв. Oleksii Kyslytsyn atsakymas sausio 28 d 2016-01-28 21:53 '16 at 21:53 2016-01-28 21:53

Galite atsijungti nuo visų kilpų nenaudodami etiketės: ir vėliavų.

Tai tik sunkus sprendimas.

Čia 1 sąlyga yra sąlyga, naudojama sulaužyti su kilpomis K ir J. Ir 2 sąlyga yra būklė, naudojama nutraukti K, J ir I ciklus.

Pavyzdžiui:

 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"); } } 
4
21 мая '14 в 17:33 2014-05-21 17:33 atsakymą pateikė Hitendra Hckr gegužės 21 d., 14 val. 17:33 2014-05-21 17:33

Naudokite sparčiuosius klavišus.

 INNER:for(int j = 0; j < numbers.length; j++) { System.out.println("Even number: " + i + ", break from INNER label"); break INNER; } 

Žr. Šį straipsnį

3
01 июня '14 в 15:41 2014-06-01 15:41 atsakymą pateikė Rumesh Eranga 01 birželio 14 d. 15:41 2014-06-01 15:41

Geriausias ir paprastas būdas.

 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; } } 
3
24 авг. Atsakymas, kurį pateikė Keshav bansal 24 rug . 2015-08-24 00:04 '15 - 0:04 2015-08-24 00:04

Tai gana neįprastas metodas, tačiau pagal kodo ilgį ( ne našumą ) tai yra paprasčiausias dalykas, kurį galėtumėte padaryti:

 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 } } 
3
26 апр. atsakymas, kurį pateikė user2875404 Bal 26 2015-04-26 01:01 '15 - 1:01 2015-04-26 01:01

Kitas be minėto pavyzdžio paminėtas sprendimas (jis tikrai veikia 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. } 

Žinoma, „ BreakLoopException turi būti vidinis, privatus ir pagreitintas be kamino stebėjimo:

 private static class BreakLoopException extends Exception { @Override public StackTraceElement[] getStackTrace() { return new StackTraceElement[0]; } } 
3
10 окт. atsakymas duotas ursa 10 oct. 2014-10-10 16:57 '14, 16:57 2014-10-10 16:57

Jei tai yra tam tikros funkcijos viduje, kodėl jūs tiesiog grąžinate:

 for (Type type : types) { for (Type t : types2) { if (some condition) { return value; } } } 
3
25 авг. atsakymą pateikė Chit Khine 25 rug . 2016-08-25 14:25 '16 at 14:25 pm 2016-08-25 14:25

Demonstracija break , continue , label .

Taigi žodžiai „Java“ break ir continue turi numatytas reikšmes, tai „artimiausia kilpa“, „Toady“ praėjus keleriems metams po „Java“ naudojimo.

Atrodo retas, bet naudingas.

 import org.junit.Test;  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(); }  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); } } }  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); } } }  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); } } } }  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); } } } } } 
2
04 мая '17 в 10:41 2017-05-04 10:41 atsakymas pateikiamas Bill gegužės 4 d. 17 d
 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; } } 
2
12 сент. Atsakymą pateikė Panzercrisis 12 Sep 2013-09-12 01:14 '13 ne 1:14 2013-09-12 01:14

for (int j = 0; j < 5; j++)//inner loop turėtų būti pakeista for (int j = 0; j < 5 !exitloops; j++) .

Šiuo atveju užbaigtos įdėtos kilpos turėtų būti užbaigtos, jei sąlyga yra True . Bet jei mes naudojame „ exitloops tik viršutinėje loop

  for (int i = 0; i < 5  !exitloops; i++) //upper loop 

Tada vidinė kilpa tęsis, nes nėra jokios papildomos vėliavos, kuri praneštų apie šią vidinę kilpą išeiti.

Pavyzdys: jei i = 3 ir j=2 tada būklė yra false . Tačiau kitoje vidinės kilpos iteracijoje j=3 sąlyga (i*j) tampa 9 kuri yra true bet vidinė kilpa tęsis, kol j tampa 5 .

Todėl ji taip pat turi naudoti vidines kilpas.

 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); } } 
2
08 апр. Atsakymą pateikė Vikrant Kashyap. 2016-04-08 07:29 '16 at 7:29 2016-04-08 07:29

Norėjau atsakyti į šį klausimą, tačiau buvo pažymėtas kaip dublikatas, kuris neleidžia publikuoti. Taigi atsiųsk čia!

Jei tai yra naujas įgyvendinimas, galite pabandyti perrašyti logiką taip, tarsi-else_if-other.

 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 } } 

Priešingu atveju, galite pabandyti nustatyti vėliavą, jei ši speciali sąlyga yra, ir patikrinkite šią vėliavą kiekvienoje jūsų ciklo aplinkoje.

 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) { // things below will not be executed continue; } // other things may happen here as well but will not be executed // once control is returned from the inner cycle } HERE! So, while a simple break will not work, it can be made to work using continue. 

Jei tiesiog perkeliate logiką iš vienos programavimo kalbos į java ir tiesiog norite gauti šį darbą, galite pabandyti naudoti nuorodas

2
01 апр. Atsakymas pateikiamas Ravindra HV balandžio 1 d. 2017-04-01 22:54 '17, 10:54 pm 2017-04-01 22:54

Kaip ir sąlyga „@ 1800“, naudokite sąlygą, kuri pažeidžia vidinę kilpą kaip išorinės kilpos būklę:

 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; } } } 
2
13 сент. Atsakymas pateikiamas mtyson rugsėjo 13 d 2014-09-13 22:00 '14 22:00 val. 2014-09-13 22:00

Kai kuriais atvejais galime efektyviai naudoti while .

 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; } 
1
24 марта '17 в 4:43 2017-03-24 04:43 atsakymą Dharmik Patel pateikė kovo 24 d. 17 d. 4:43 2017-03-24 04:43

Galite atlikti šiuos veiksmus:

  1. nustatyti vietinį kintamąjį false

  2. nustatyti, kad šis kintamasis būtų true pirmoje kilpoje, kai norite nutraukti

  3. tada galite patikrinti išorinę kilpą ir nustatyti, ar būsena bus nustatyta, ir išeiti iš išorinės kilpos.

     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 } } 
1
19 сент. atsakymą pateikė Siddharth Choudhary 2017-09-19 08:41 '17 8:41 am 2017-09-19 08:41

Net kuriant išorinės kilpos vėliavą ir patikrinus, ar po kiekvieno vidinės kilpos vykdymo gali būti atsakymas.

Patinka tai:

 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; } 
1
28 апр. atsakymas duotas tejas Balandžio 28 d 2013-04-28 08:08 '13, 08:08 2013-04-28 08:08
 boolean condition = false; for (Type type : types) { for (int i = 0; i < otherTypes.size  !condition; i ++) { condition = true; // if your condition is satisfied } } 

Kai baigsite apdoroti, naudokite sąlygą kaip vėliavą. Tada vidinė kilpa tęsiasi tol, kol bus įvykdyta sąlyga. Bet kuriuo atveju, išorinė kilpa tęsis.

0
11 июля '14 в 19:46 2014-07-11 19:46 atsakymą atsiuntė astryk liepos 14 d. 14, 19:46 2014-07-11 19:46

„Java“ neturi „goto“ funkcijos, kaip ir „C ++“. Tačiau vis dėlto „ goto yra „Java“ rezervuotas raktinis žodis. Jie gali tai realizuoti ateityje. Jūsų klausimu atsakymas yra toks, kad „Java“ yra kažkas vadinama etikete, kuriai galite taikyti continue ir break pareiškimą. Raskite toliau pateiktą kodą:

 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"); } 
0
04 авг. atsakymas, kurį pateikė Harsh Vardhan 04 rug. 2018-08-04 14:38 '18, 14:38 pm 2018-08-04 14:38

Įsitikinkite, kad vidinė kilpa yra baigta naudojant if pareiškimą, patikrinant vidinės kilpos kintamąjį. Taip pat galite sukurti kitą kintamąjį, pvz., Loginį, kad patikrintumėte, ar vidinė kilpa išėjo.

Šiame pavyzdyje jis naudoja vidinio kontūro kintamąjį, kad patikrintų, ar jis buvo:

 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 } } 
-1
07 мая '13 в 21:57 2013-05-07 21:57 atsakymas duotas Edd 07 gegužės 13 d. 21:57 2013-05-07 21:57

Naudodami etiketę naudokite vidines kilpas.

 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"); } } 
-1
17 окт. Atsakymą pateikė Mahesh P Oct 17. 2012-10-17 14:50 '12, 2:50 val. 2012-10-17 14:50
  • 1
  • 2

Kiti klausimai apie „ žymes arba Užduoti klausimą