7

Hi I am beginner in java and my program has 4 for loops: my program works like this that if b is true ,the element will be removed from pointList and n will be n-- and the I want to go out from all for loops and come again from the first for loop so l will be l++,how can i do this ? with break statement?

for (int l = 0; l < n; l++) {
  for (int i = 1; i < (n - 2); i++) {
      for (int j = i + 1; j < (n - 1); j++) {
          for (int k = j + 1; k < n; k++) {
              if (l != i && l != j && l != k) {
                  boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                  System.out.println(b);
                  if (b == true) {
                      pointList.remove(pointList.get(l);
                      n--;
                      break;
                  }
                  else
                      System.out.println(b);
              }
           }
       }
    }
}
codaddict
  • 445,704
  • 82
  • 492
  • 529
user472221
  • 3,014
  • 11
  • 35
  • 42
  • duplicate http://stackoverflow.com/questions/551578/how-to-break-multiple-foreach-loop – SunnyShah Nov 18 '10 at 11:02
  • Maybe you can describe in a few words what do you want to do? "remove l-th item if b is true". Your code contains syntax errors. Fix it, please, and clarify your question. – khachik Nov 18 '10 at 11:02
  • It looks like you are trying to find 4 elements which meet some criteria. If you explained what the criteria was, perhaps we could suggest a simpler way of doing the same thing. e.g. perhaps sorting the list first might simplify the loops. – Peter Lawrey Nov 18 '10 at 11:04
  • OMG! Is it realy neccessary to walk through in this way? Please [avoid](http://en.wikipedia.org/wiki/Software_quality) cascading loops.. – elCapitano Nov 18 '10 at 11:01
  • +1 - Nearly useless link, but I agree with the advice anyway. – T.E.D. Nov 18 '10 at 11:08
  • One option might be http://www.aivosto.com/project/help/pm-complexity.html , which near the bottom suggests you should try to prevent loops from nesting more than two deep. – T.E.D. Nov 18 '10 at 11:14
  • Because of runtime-issues and structural behaviour (and others) you should avoid cascading loops. Using deep recursions can be a hint for bad design of your programm. Cant your function run without this recursion? (perhaps using functions, objects or anything like this to get your needs satisfied) – elCapitano Nov 18 '10 at 11:18

9 Answers9

17

You can make use of a labeled break as:

      for (int l = 0; l < n; l++) {
 foo:    for (int i = 1; i < (n - 2); i++) {
            for (int j = i + 1; j < (n - 1); j++) {
                for (int k = j + 1; k < n; k++) {
                    if (l != i && l != j && l != k) {
                        boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                        System.out.println(b);
                        if (b == true) {
                            pointList.remove(pointList.get(l);
                            n--;
                            break foo;
                        }
                        else
                            System.out.println(b);
                    }

                }

            }
        }
    }
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • it will break just the last three for loops and then it will start with the first loop and goes within those three for loops too? – user472221 Nov 18 '10 at 11:13
  • 1
    You could consider any branching statement to be a "goto in disguise" I suppose. But they all have their limits and their uses. Even goto itself does, actually (state machines are a PITA without it). – T.E.D. Nov 18 '10 at 11:17
  • didn0t event know that there are labeld breaks in java :D – RoflcoptrException Nov 19 '10 at 11:27
5

In a loop the break statement terminates the inner loop while continue skips to the next iteration. In order for these two statements to work on a different loop to the inner one you need to use labels. Something like this should work:

outerloop:      
        for (int l = 0; l < n; l++) {
            for (int i = 1; i < (n - 2); i++) {
                for (int j = i + 1; j < (n - 1); j++) {
                    for (int k = j + 1; k < n; k++) {
                        if (l != i && l != j && l != k) {
                            boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                            System.out.println(b);
                            if (b == true) {
                                pointList.remove(pointList.get(l);
                                n--;
                                continue outerloop;
                            }
                            else
                                System.out.println(b);
                        }

                    }

                }
            }
        }
brain
  • 5,496
  • 1
  • 26
  • 29
3

Have a look at the labeled break statement

for example here: Branching Statements

eric
  • 1,857
  • 5
  • 23
  • 33
3
String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
  for(Object2 object2: object1){
    //I get some value from object2
    valueFromObj2 = object2.getSomeValue();
    for(Object3 object3 : object2){
      for(Object4 object4: object3){
        //Finally I get some value from Object4.
        valueFromObj4 = object4.getSomeValue();
        //Compare with valueFromObj2 to decide either to break all the foreach loop
        if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
          break OUTERMOST;
        }
      }//fourth loop ends here
    }//third loop ends here
  }//second loop ends here
}//first loop ends here
SunnyShah
  • 28,934
  • 30
  • 90
  • 137
2

Use a labeled loop

for (int l = 0; l < n; l++) {
    loopa:
    for (int i = 1; i < (n - 2); i++) {
        for (int j = i + 1; j < (n - 1); j++) {
            for (int k = j + 1; k < n; k++) {
                if (l != i && l != j && l != k) {
                    boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                    System.out.println(b);
                    if (b == true) {
                        pointList.remove(pointList.get(l);
                        n--;
                        break loopa;
                    }
                    else
                        System.out.println(b);
                }

            }

        }
    }
}

and then break from the labeled loop

stjohnroe
  • 3,168
  • 1
  • 27
  • 27
  • it will break just the last three for loops and then it will start with the first loop and goes within those three for loops too? – user472221 Nov 18 '10 at 11:13
  • Functionally equivalent to that from Brain. In that it will kick into the next iteration of the outermost loop – stjohnroe Nov 18 '10 at 14:01
1
again:
for (int l = 0; l < n; l++) {
        for (int i = 1; i < (n - 2); i++) {
            for (int j = i + 1; j < (n - 1); j++) {
                for (int k = j + 1; k < n; k++) {
                    if (l != i && l != j && l != k) {
                        boolean b = isOK(pointList.get(l), pointList.get(i),  pointList.get(j), pointList.get(k));
                        System.out.println(b);
                        if (b == true) {
                            pointList.remove(pointList.get(l);
                            n--;
                            break again;
                        }
                        else
                            System.out.println(b);
                    }

                }

            }
        }
    }
2red13
  • 11,197
  • 8
  • 40
  • 52
1

I agree with all the other answers. However, I'd like to point out that an alternative to exit would be to just put that code in its own routine and use a return statement to break out of the whole thing. Your quad-nested loop is so complex by itself that it probably deserves to be in its own routine anyway.

I've worked on DoD jobs that required a cyclomatic complexity of no more than 6 for any one routine (with some exceptions). This series of loops alone is 4. If you can't find a simpler way to do it, you really ought to chuck them in their own routine just to preserve the sanity of the poor schmucks who have to maintain this code.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
0

A first 'quick and dirty' solution would be to use a stay_into_loops variable and modify the for loops like:

 boolean stay_into_loops = true
 // here goes the first for loop
 for (int i = 1; i < (n - 2) && stay_into_loops ; i++) {
            for (int j = i + 1; j < (n - 1) && stay_into_loops ; j++) {
                for (int k = j + 1; k < n && stay_into_loops ; k++) {
                    if (l != i && l != j && l != k) {
                        boolean b = isOK(pointList.get(l), `pointList.get(i), pointList.get(j), pointList.get(k));`
                        System.out.println(b);
                        if (b == true) {
                            pointList.remove(pointList.get(l);
                            n--;
                            stay_into_loops = false;
                            break;

However it is generally a code smell when you encounter things like these. Consider refactoring the code because this will escalate into a mess at some point.

lorenzog
  • 3,483
  • 4
  • 29
  • 50
0

Create an exit for yourself in each inner for loop.
Here's a quick and painless solution.

  bool breakout;
  for (int l = 0; l < n; l++) 
  {
        breakout = false;
        for (int i = 1; i < (n - 2) && !breakout; i++)
            for (int j = i + 1; j < (n - 1) && !breakout; j++)
                for (int k = j + 1; k < n && !breakout; k++)
                {
                    if(b == true)
                        breakout = true;                            
                }
  }

So you see the breakout boolean is your ticket out of each inner loop, coz it gets checked in every for declaration. And it gets reset every time the first for iterates.

BeemerGuy
  • 8,139
  • 2
  • 35
  • 46