旧行李
2009-05-20 09:07
采纳率: 25%
浏览 413
已采纳

如何在 Java 中突破嵌套循环?

I've got a nested loop construct like this:

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

Now how can I break out of both loops. I've looked at similar questions, but none concerns Java specifically. I couldn't apply these solutions because most used gotos.

I don't want to put the inner loop in a different method.

Update: I don't want to rerun the loops, when breaking I'm finished with the execution of the loop block.

转载于:https://stackoverflow.com/questions/886955/how-to-break-out-of-nested-loops-in-java

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

29条回答 默认 最新

  • 胖鸭 2009-05-20 09:11
    已采纳

    Like other answerers, I'd definitely prefer to put the inner loop in a different method. This answer just shows how the requirements in the question can be met.

    You can use break with a label for the outer loop. For example:

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

    This prints:

    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
    
    已采纳该答案
    打赏 评论
  • 狐狸.fox 2009-05-20 09:11

    You can use labels:

    label1: 
    for (int i = 0;;) {
        for (int g = 0;;) {
          break label1;
        }
    }
    
    打赏 评论
  • 狐狸.fox 2009-05-20 09:11

    You can use a temporary variable:

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

    Depending on your function, you can also exit/return from the inner loop:

    for (Type type : types) {
        for (Type t : types2) {
             if (some condition) {
                 // Do something and break...
                 return;
             }
        }
    }
    
    打赏 评论
  • You can use a named block around the loops:

    search: {
        for (Type type : types) {
            for (Type t : types2) {
                if (some condition) {
                    // Do something and break...
                    break search;
                }
            }
        }
    }
    
    打赏 评论
  • csdnceshi62 2009-05-20 11:43

    maybe with a function?

    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;
          }
        }
      }
    }
    
    打赏 评论
  • 喵-见缝插针 2011-11-14 18:26

    Technically the correct answer is to label the outer loop. In practice if you want to exit at any point inside an inner loop then you would be better off externalizing the code into a method (a static method if needs be) and then call it.

    That would pay off for readability.

    The code would become something like that:

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

    Matching the example for the accepted answer:

     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);
                }
            }
        }
    }
    
    打赏 评论
  • 北城已荒凉 2011-12-07 17:52

    I never use labels. It seems like a bad practice to get into. Here's what I would do:

    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;
            }
        }
    }
    
    打赏 评论
  • MAO-EYE 2012-02-05 06:04

    I needed to do a similar thing, but I chose not to use the enhanced for loop to do it.

    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;
            }
        }
    }
    
    打赏 评论
  • 狐狸.fox 2012-10-17 11:50

    You just use label for breaking inner loops

    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");
    }
    }
    
    打赏 评论
  • 撒拉嘿哟木头 2013-04-28 05:08

    Even creating a flag for outer loop and checking that after each execution of inner loop can be the answer.

    Like this :

    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;
    }
    
    打赏 评论
  • 北城已荒凉 2013-05-07 18:57

    Check if the inner loop is exited with an if statement, by checking the inner loop's variable. You could also create another variable such as a boolean to check if the inner loop is exited.

    In this example it uses the inner loop's variable to check if it has been exited:

    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   
         } 
    }
    
    打赏 评论
  • 三生石@ 2013-09-11 22:14
    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;
        }
    }
    
    打赏 评论
  • local-host 2013-12-21 22:56

    If you don't like breaks and gotos, you can use a "traditional" for loop instead the for-in, with an extra abort condition:

    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;
            }
        }
    }
    
    打赏 评论
  • 七度&光 2014-05-21 14:33

    You can break from all loops without using any label: and flags.

    It's just tricky solution.

    Here condition1 is the condition which is used to break from loop K and J. And condition2 is the condition which is used to break from loop K , J and I.

    For example:

    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");
        }
    }
    
    打赏 评论
  • larry*wei 2014-06-01 12:41

    Use Labels.

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

    Refer to this article

    打赏 评论
  • local-host 2014-07-11 16:46
    boolean condition = false;
    for (Type type : types) {
        for (int i = 0; i < otherTypes.size && !condition; i ++) {
            condition = true; // if your condition is satisfied
        }
    }
    

    Use condition as a flag for when you are done processing. Then the inner loop only continues on while the condition has not been met. Either way the outer loop will keep on chuggin'.

    打赏 评论
  • 叼花硬汉 2014-08-04 17:29

    I prefer to add an explicit "exit" to the loop tests. It makes it clear to any casual reader that the loop may terminate early.

    boolean earlyExit = false;
    for(int i = 0 ; i < 10 && !earlyExit; i++) {
         for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
    }
    
    打赏 评论
  • 零零乙 2014-09-13 19:00

    Like @1800 INFORMATION suggestion, use the condition that breaks the inner loop as a condition on the outer loop:

    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;
            }
        }
    }
    
    打赏 评论
  • 七度&光 2014-10-10 13:57

    Another one solution, mentioned without example (it actually works in 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.
    }
    

    Of course BreakLoopException should be internal, private and accelerated with no-stack-trace:

    private static class BreakLoopException extends Exception {
        @Override
        public StackTraceElement[] getStackTrace() {
            return new StackTraceElement[0];
        }
    }
    
    打赏 评论
  • 谁还没个明天 2015-04-25 22:01

    Rather unusual approach but in terms of code length (not performance) this is the easiest thing you could do:

    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
        }
    }
    
    打赏 评论
  • local-host 2015-08-23 21:04

    Best and Easy Method..

    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;
         }
    }
    
    打赏 评论
  • 旧行李 2016-01-28 18:53

    Rather for a long I was thinking to share this type of answer for this type of question.

    Usually such cases are come in scope of a more meaningful logic, let's say some searching or manipulating over some of the iterated 'for'-objects in question, so I usually use the functional approach:

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

    Major cons:

    • roughly twice more lines
    • more consumption of computing cycles, meaning it is slower from algorithmic point-of-view
    • more typing work

    The pros:

    • the higher ratio to separation of concerns because of functional granularity
    • the higher ratio of re-usability and control of searching/manipulating logic without
    • the methods are not long, thus they are more compact and easier to comprehend
    • subjectively higher ratio of readability

    So it is just handling the case via a different approach.

    Basically a question to the author of this question: what do you consider of this approach?

    打赏 评论
  • 乱世@小熊 2016-04-08 04:29

    for (int j = 0; j < 5; j++) //inner loop should be replaced with for (int j = 0; j < 5 && !exitloops; j++).

    Here, in this case complete nested loops should be exit if condition is True . But if we use exitloops only to the upper loop

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

    Then inner loop will continues, because there is no extra flag that notify this inner loop to exit.

    Example : if i = 3 and j=2 then condition is false. But in next iteration of inner loop j=3 then condition (i*j) become 9 which is true but inner loop will be continue till j become 5.

    So, it must use exitloops to the inner loops too.

    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);
        }
    }
    
    打赏 评论
  • perhaps? 2017-03-24 01:43

    For some cases, We can use while loop effectively here.

    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;
    }
    
    打赏 评论
  • Didn"t forge 2017-04-01 19:54

    I wanted to answer this question but was marked as a duplicate which prevents me from posting as well. So posting it here instead !

    If its a new implementation you can try re-writing the logic as if-else_if-else statements.

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

    Otherwise you can try setting a flag when that special condition has occured and check for that flag in each of your loop-conditions.

    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.
    

    If you are simply porting the logic from one programming language to java and just want to get the thing working you can try using labels

    打赏 评论
  • python小菜 2017-05-04 07:41

    Demo for break, continue, label.

    So java keywords break and continue have default value, it's the "Nearest Loop", Toady a few years after use Java, I just got it !

    It's seem used rare, but useful.

    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);
                    }
                }
            }
        }
    
    }
    
    打赏 评论
  • csdnceshi62 2017-07-16 10:24

    Java 8 Stream solution:

    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**/);
    
    打赏 评论
  • 狐狸.fox 2017-09-19 05:41

    You can do the following:

    1. set a local variable to false

    2. set that variable true in the first loop, when you want to break

    3. then you can check in the outer loop, that whether the condition is set then break from the outer loop as well.

      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
          }
      }
      
    打赏 评论
  • 北城已荒凉 2018-08-04 11:38

    Java does not have a goto feature like there is in C++. But still, goto is a reserved keyword in Java. They might implement it in the future. For your question, the answer is that there is something called label in Java to which you can apply a continue and break statement. Find the code below:

    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");
    }
    
    打赏 评论

相关推荐 更多相似问题