How do I break out of nested loops in Java?

前端 未结 30 2629
梦毁少年i
梦毁少年i 2020-11-21 11:51

I\'ve got a nested loop construct like this:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do somethin         


        
相关标签:
30条回答
  • 2020-11-21 12:04

    Usually in such cases, it is coming in scope of 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
    • 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?

    0 讨论(0)
  • 2020-11-21 12:05

    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];
        }
    }
    
    0 讨论(0)
  • 2020-11-21 12:05

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 12:05

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 12:07

    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
          }
      }
      
    0 讨论(0)
  • 2020-11-21 12:08

    Demo for break, continue, and label:

    Java keywords break and continue have a default value. It's the "nearest loop", and today, after a few years of using 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);
                    }
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题