35

If I use break like the code below, then the loop within row won't iterate the rest if there is a match in the beginning, but what about the col loop?

Would it still iterate between 0 and 7? Is there a way to use break there as well?

for (int col = 0; col < 8; col ++)
    for (int row = 0; row < 8; row ++)
        if (check something)
        {
            //Then do this;
            break;
        }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3D-kreativ
  • 9,053
  • 37
  • 102
  • 159
  • 2
    It won't break the outer loop, you would need to include a similar check there - maybe set a bool in the inner break. – Roger Rowland May 27 '13 at 09:12
  • 4
    Yes, it would continue to loop the outer loop. The way to break this is called `goto`. – JeffRSon May 27 '13 at 09:12
  • It will break out the inner loop only, set some bool after "Then do this" and check after your inner loop. – TheKingDave May 27 '13 at 09:13
  • 1
    Set col to 8 would work – Sayse May 27 '13 at 09:14
  • 2
    @Sayse: unless he changes the limit of the loop ;) – Marco Forberg May 27 '13 at 10:30
  • 2
    Ah, breaking out of multiple loops.. the ultimate question. It seems so obvious but I wish there was some better language support rather than using a sentinel boolean. E.g. something like break(2) which breaks out twice. I mean, how hard can it be. – Thomas May 27 '13 at 11:05
  • @Thomas It's as simple as a `goto`, although not recommended, as it makes reading the code that much harder. – Nolonar May 27 '13 at 11:36
  • @Nolonar Yeah, I knew about the goto but it is kind of a hack, and as you said, it makes the code difficult to follow. – Thomas May 27 '13 at 11:37
  • @Thomas there are languages, like php, that support that syntax and semantics. – nsn May 27 '13 at 15:06
  • Unless you really have to do it for some mysterious reason (and that is usually veeeeeeeeery rare) AVOID breaks and especially goto's. That's the first sign that something is really wrong with your code logic. – nsn May 27 '13 at 15:09
  • 1
    @nsn I think that's just cargo-cult dogmatism. `break outerLoop` and `goto outside` are both well-known idioms that can immediately be understood. – Peter Olson May 27 '13 at 21:22
  • c# case already answered some years before [here](http://stackoverflow.com/q/324831/1178314). And there are answers stating about java case there too. – Frédéric Sep 07 '15 at 14:56

13 Answers13

90

One option is to use a condition flag. You could then either break in the outer loop as well, or just use it as an extra condition within the for loops:

bool keepGoing = true;

for (int col = 0; col < 8 && keepGoing; col++)
{
    for (int row = 0; row < 8 && keepGoing; row++)
    {
        if (something)
        {
             // Do whatever
             keepGoing = false;
        }
    }
}

In Java, you can specify a label to break to though. (I didn't see that this question was tagged Java as well as C#.)

outerLoop:
for (...)
{
    for (...)
    {
        if (...)
        {
            break outerLoop;
        }
    }
}

EDIT: As noted in comments, in C#, you could use a label and goto:

for (...)
{
    for (...)
    {
        if (...)
        {
            goto endOfLoop;
        }
    }
}
endOfLoop:
// Other code

I'd really recommend that you don't take either of these approaches though.

In both languages, it would usually be best to simply turn both loops into a single method - then you can just return from the method:

public void doSomethingToFirstOccurrence()
{
    for (...)
    {
        for (...)
        {
            if (...)
            {
                return;
            }
        }
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks for the answer. Today I'm using Java. Can I use col < 8 && keepGoing; in Java also? – 3D-kreativ May 27 '13 at 09:17
  • 14
    @3D-kreativ: Yes, but I'd still recommend using the "extract to method" approach. – Jon Skeet May 27 '13 at 09:20
  • OK, but which one used the "extract to method" or what do you mean? – 3D-kreativ May 27 '13 at 09:22
  • @3D-kreativ: The bottom one - you move the two loops into a method on their own, which you can return from. – Jon Skeet May 27 '13 at 09:24
  • Aha! OK I got it, so it return from the method and leave both loop immediately when the if statement is achieved? – 3D-kreativ May 27 '13 at 09:32
  • 4
    @3D-kreativ Yes, `return` exits the current method instantly. Except if you have a `finally` block, in which case the content of the `finally` block will be executed **before** exiting the current method, which is meant for closing open connections or disposing of objects or the likes. – Nolonar May 27 '13 at 09:47
  • @3D-kreativ I just noticed my previous comment might not have been very clear: In order for the `finally` block to be executed, the `return` statement has to be called from within a `try` block that is linked with a `finally` block: `try { return; } finally { /* will always be executed when previous 'try' has finished, even when 'return' was called, or exception was thrown */ }`. Aside from the aforementioned `try-finally`, return will **always** exit the current method instantly. – Nolonar May 27 '13 at 10:04
  • In C# you can't break with a label, but you can break out using `goto` to a label right after the loop. – Peter Olson May 27 '13 at 21:14
  • Just out of curiosity, why do you have more repulsion to the `goto endOfLoop` than `break outerLoop`? The `goto` actually looks a little bit more straightforward to me in this case. Is there any disadvantage to the `goto` here other than that there's a big stigma about it? – Peter Olson May 27 '13 at 21:28
  • @PeterOlson: Oh I have a revulsion to both. In both cases I think it hurts readability, and I'd much rather refactor it away into a separate method. I can't remember the last time I used `goto` except when reproducing the async generated code, and I can't remember using a labelled `break` in Java either. – Jon Skeet May 27 '13 at 21:31
  • 1
    Right, I would definitely agree that refactoring into a separate method is superior to either approach, I just thought it was odd that you didn't really warn against using `break`, but you did so somewhat emphatically for `goto`. – Peter Olson May 27 '13 at 21:38
  • @PeterOlson: Right - edited to make it clearer that I don't like either of them :) – Jon Skeet May 27 '13 at 21:56
  • I want to weigh in here because it really needs to be said. goto isn't nice to read. You should avoid it where possible. However, in C#, breaking nested loops is one of two places where goto is actually the 'best way'. It is concise and quick. The other 'best use' is case statement fall-though, where it is required. – Gusdor May 28 '13 at 08:08
  • @Gusdor: Better than refactoring to a method, in your view? – Jon Skeet May 28 '13 at 08:09
  • @JonSkeet i would say it depends on the length of the inner loop code. There will come a point where it is a stylistic choice focussed on legibility - no one wants huge methods. Personally, I try to avoid overly specific private methods as I feel it causes bloat. – Gusdor May 28 '13 at 08:14
  • @Gusdor: You'd have to define "bloat" for me to agree or not, to be honest. But I can't remember the last time I regretted extracting a nested loop out of a method and giving it a really good name instead - I find it increases readability significantly. Mind you, often nested loops can be converted into LINQ queries instead... – Jon Skeet May 28 '13 at 08:17
  • In my world, bloat is extra syntax (therefore, lines) that you dont need. In this case it would be the method declaration for (at its smallest) a 4 line 'if-else'. Next time I hit some nested loops I shall give your method a shot sir. – Gusdor May 28 '13 at 08:20
  • 2
    @Gusdor: Readability is about much more than just line count. Often you can find a relatively long method can be broken into several short methods each of which tackles a single aspect, and one "coordinator" method which just calls each method in turn. While the code ends up being longer, it can be *much* quicker to read that way. – Jon Skeet May 28 '13 at 08:24
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30735/discussion-between-gusdor-and-jon-skeet) – Gusdor May 28 '13 at 08:28
  • @Jon, by 'coordinator' method I believe you mean the '[Composed Method](http://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html)'. Right? – publicgk Feb 20 '14 at 06:30
15

Yes, it is possible by using a break label:

package others;

public class A {

    public static void main(String[] args) {
        outer: for(int col = 0; col < 8; col ++)
        {
            for (int row = 0; row < 8; row ++)
            {
                if (col == 4)
                {
                    System.out.println("hi");
                    break outer;
                }
            }
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
anshulkatta
  • 2,044
  • 22
  • 30
6

You can put logic like this:

boolean condition = false;

for (int col = 0; col < 8; col ++)
    for (int row = 0; row < 8; row ++)
        if (check something) {
            // Then do this:
            condition = true; // Break condition for outer loop
            break;
        }
     }
     if (condition)
         break;
 }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
3

It doesn't exit the col loop.

Instead, you can wrap all in a function and use return; to exit immediately from the loop

private Xy Loop( /* Parameters */)
    for (int col = 0; col < 8; col ++)
        for (int row = 0; row < 8; row ++)
            if (check something) {
                // Then do this;
                return something; //Or just return;
            }
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fabio Marcolini
  • 2,315
  • 2
  • 24
  • 30
  • This is more useful in a language like C where you can't break multiple loops. You can use goto, but generally people say goto is a no-no. – Ryan Amos May 28 '13 at 00:43
3

break only breaks the loop that is directly around it. You could use a flag to control the outer loop:

boolean continueOuterLoop = true;

for(int col = 0; continueOuterLoop && col < 8; col ++) {
    for(int row = 0; row < 8; row ++) {
        if(check something) {
            //Then do this;
            continueOuterLoop = false;
            break;
        }
    }
}
Marco Forberg
  • 2,634
  • 5
  • 22
  • 33
3
nameHere:
for (yourForLoop) {
    for (anotherLoop) {
        if(condition) {
            break nameHere;
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Michael 'Maik' Ardan
  • 4,213
  • 9
  • 37
  • 60
2

One more alternative to the other answers is to set your counters to the maximum, to stop the loops.

for (int col = 0; col < 8; col ++)
    for (int row = 0; row < 8; row ++)
        if (check something)
        {
            // Use the col and row here.

            // Now we go for a totally break of all loops.
            // To stop the loops you can set that to the maximum
            // of your loop test.
            row = 8;
            col = 8;
        }

The advantage to that trick is that you do not add any additional checking code to the full loop and that makes it a lot faster.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aristos
  • 66,005
  • 16
  • 114
  • 150
2

In Java, you can use a break label.

outer: 
for (int col = 0; col < 8; col ++)
    for (int row = 0; row < 8; row ++)
        if (check something)
        {
            break outer;
        }
    }
}

And, since nobody else has mentioned it yet, in C#, you can use goto label.

for (int col = 0; col < 8; col ++)
    for (int row = 0; row < 8; row ++)
        if (check something)
        {
            goto outside;
        }
    }
}
outside:
Pang
  • 9,564
  • 146
  • 81
  • 122
Peter Olson
  • 139,199
  • 49
  • 202
  • 242
1

I think you should use a tag or a label, like "outerLoop". This works in Java:

outerLoop:
    for (int col = 0; col < 8; col ++)
        for (int row = 0; row < 8; row ++)
            if (check something)
            {
                //Then do this;
                break outerLoop;
            }
Pang
  • 9,564
  • 146
  • 81
  • 122
anddevmanu
  • 1,459
  • 14
  • 19
0

There are a few ways to do this. One way is to set the max value of the variable in the outer loop.

int maxcol = 8;
for (int col = 0; col < maxcol; col++)
{
    for (int row = 0; row < 8; row++)
    {
        if (check something)
        {
            Then do this;

            // cause the outer loop to break:
            col = maxcol;
            // break the inner loop
            break;
        }
    }
}
Jerry Joseph
  • 1,002
  • 8
  • 14
0

Set the col = 8 and then break to inner loop.

  • Manipulating the for loop counters like this is not recommended. The counter should represent the number of iterations that have passed so if you set it to 8 when you haven't don't 8 iterations is a lie. You are also using the variable for more than one purpose. – Despertar May 27 '13 at 18:08
0
Loop1: 
for (int col = 0; col < 8; col ++)
{
    for (int row = 0; row < 8; row ++)
    {
        if (condition)
        {
            break Loop1;
        }
    }
}

This could do what you need.

Pang
  • 9,564
  • 146
  • 81
  • 122
Ramesh
  • 163
  • 1
  • 2
  • 11
-1

We could use the concept of a flag variable:

flag = 1;
for (int col = 0; col < 8; col ++)
{
    if (flag == 1)
    {
        for (int row = 0; row < 8; row ++)
        {
            if (flag == 1)
            {
                if (check something)
                {
                    //Then do this;
                    flag = 0;
                }
            }
        }
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122