2

What is the best way to end a loop in Java?

This:

boolean exit = false;

while((a < 5) && (exit = false)){
   if(a == 3)
       exit = true;
   else
       a++;
}

Or this:

while((a < 5){
   if(a == 3)
       break;
   else
       a++;
}
Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76
mugimugi
  • 446
  • 7
  • 19
  • 4
    my opinion on this is that it really is a matter of opinion. alternatives to your to options include exceptions and return statements as well. – njzk2 Feb 06 '15 at 15:19
  • 1
    http://stackoverflow.com/questions/3922599/is-it-a-bad-practice-to-use-break-in-a-for-loop , http://stackoverflow.com/questions/18188123/is-it-bad-practice-to-use-break-to-exit-a-loop-in-java , http://programmers.stackexchange.com/questions/58237/are-break-and-continue-bad-programming-practices – Sikorski Feb 06 '15 at 15:22
  • Omit the redundant `else` in the second snippet. – xehpuk Feb 06 '15 at 15:24

7 Answers7

4

Some people may find that break are harder to debug (personally, I prefer using flag) but it is principally a matter of opinion.

Imagine a loop body which contains over 500 lines of code, with some break statements located everywhere, it may be harder for you to visualise all the possibilities of exiting the loop.

Another reason of why I like using a flag is that you can give a signifiant name to the ending point instead of simply break.

Note that you can also use a flag in a for loop example :

boolean flag = false;
for(int i = 0; !flag && i < 10; i++) {
// some treatment
}

It may be interesting however, to know that when dealing with loop, there is the continue keyword which allow you to not exit the loop, but skip directly to the next iteration.

What is the best way to finish a loop in Java?

If there was really a best way between both, Java would probably not allow the other ;)

I guess the most important is to use the same convention as your co-worker so the code does not differ from class to class.

Mark Stewart
  • 2,046
  • 4
  • 22
  • 32
Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76
  • 6
    I find `break` more straightforward and flags harder to debug, specially if you have multiple flags. Of course, it is primary opinion-based. – Christian Tapia Feb 06 '15 at 15:19
  • 1
    I have actually received a lot of grief for using flags in for loops. However for you to say you should `not` use something that is in the language spec seems a bit rediculous – austin wernli Feb 06 '15 at 15:19
  • @Christian @austinwernli, I edited to state that this is mostly a matter of opinion, however I've added an example of a case where I personally find `break` are harder to debug but this is again an opinion. – Jean-François Savard Feb 06 '15 at 15:24
  • 3
    "Imagine a `loop` body which contains over 500 lines of code" - please don't write code like that. – xehpuk Feb 06 '15 at 15:26
  • 1
    imagine keeping track of that "simple" boolean flag, instead of quick break ! – Sikorski Feb 06 '15 at 15:27
  • @xehpuk I don't but some people do. I had many times to debug huge loop at job full of `break` everywhere. – Jean-François Savard Feb 06 '15 at 15:27
  • 1
    @Jean-FrançoisSavard That's not a problem with `break` but a general problem with the code. – xehpuk Feb 06 '15 at 15:28
  • Of of the main reason of why I like `flag` is that you can give a signifiant name to the `break` instead of just `break`. – Jean-François Savard Feb 06 '15 at 15:29
  • @Jean-FrançoisSavard: as Sikorski said, it will be very hard if you have to keep track of a flag in the code, specially if it changes its value in multiple parts of the code. – Christian Tapia Feb 06 '15 at 15:30
  • Oh well, I never experienced any problem with that... But anyway I'm not saying `flag` is better, I'm just saying its mostly a matter of opinion and my opinion tend more to use the `flag` probably because I've learned that way. – Jean-François Savard Feb 06 '15 at 15:32
4

break exist for a reason, right!

while(a < 5){
   if(a == 3)
       break;
   else
       a++;
}

Very simple answer, go for the break, less flags, less to debug, easier to maintain. It is simple to change from a while to for loop without any modifications in the logic. Think of a scenario where you would need to add more conditions...

My opinion is if you don't understand the usage of break and continue then you might go for the flag all the time. But there is not only one answer. Your question is what option is better for exit the loop and from your two examples the option is simple. My opinion is the break one.

Now some will use the flag, and some the break, and they give code samples for which will fit better. But this is not your question!

I can give you lots of examples, where some I would go for the flag and other for the break and some a mix of both. It depends on what my loop is about to handle.

break is to mark that if we reach this condition, we will go out of the loop emiditely. Which is very important in some loop logic. Even though when you/co-worker add more logic, before or after that condition, still the loop will exit where it reaches the break.

Sometimes you maybe want to flag that you reached a condition but want still to go thru all the instructions the loop covers, and here does a bool help you to stop the loop but after it went thru all the logic.

If you don't use flag/break in a right way your system can act very strange, specially when adding new logic.

Remember that you also can use break and continue with a label, which is not so common but good to know.

class ContinueWithLabelDemo {
    public static void main(String[] args) {

        String searchMe = "Look for a substring in me";
        String substring = "sub";
        boolean foundIt = false;

        int max = searchMe.length() - 
                  substring.length();

    test:
        for (int i = 0; i <= max; i++) {
            int n = substring.length();
            int j = i;
            int k = 0;
            while (n-- != 0) {
                if (searchMe.charAt(j++) != substring.charAt(k++)) {
                    continue test;
                }
            }
            foundIt = true;
                break test;
        }
        System.out.println(foundIt ? "Found it" : "Didn't find it");
    }
}
MrSimpleMind
  • 7,890
  • 3
  • 40
  • 45
1

The first snippet is syntactically wrong - = is the assignment operator. You were looking for the equality operator, ==:

while ((a < 5) && (exit == false)) {

Or better yet, since exit is a boolean, just evaluate it directly:

while (a < 5 && !exit) {

Other than that, you should always strive to follow the convention of the project you're working on. If it's coding styles prefers breaks - just use them. If it prohibits them, don't.

Once you throw project guideline considerations out the window, it's completely a matter of preference. Personally, I tend to prefer the break statement, especially if I have several conditions to evaluate. E.g.:

while (a < 5) {
    // do stuff
    if (a == 3) {
        break;
    }
    // do more stuff
    if (b >= 19) {
         break;
    }
    // etc...
}

But ultimately, you should evaluate it on a case-to-case basis. Preferring breaks, like I do, doesn't mean you should blindly always use them. Choose whatever makes the code look better and easier to maintain.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
0

I depends on what you mean by "best" ? With the break, you exit the loop early, so that is more efficient.

Wim Deblauwe
  • 25,113
  • 20
  • 133
  • 211
0

I would prefer the first, cause goto is considered harmful. And an exit is like a goto. But more important: Please always use {} when writing a if clause.

Also, when using a condition, give it a name. It is almost simpler to understand ageBelow18 instead of today.getYear() < customer.getBirthday().getYear(); (the code is not correct, I know).

dec
  • 594
  • 1
  • 9
  • 18
  • 2
    About the `{}` advice, I don't think it's always necessary. It all depends if it makes the code more readable. – Christian Tapia Feb 06 '15 at 15:24
  • 1
    That is correct. It is not necessary, but how many people got problems later, cause the omit it. – dec Feb 06 '15 at 15:31
  • I also think that the `{}` is really not needed when doing a simply one-line statement on a condition. – Jean-François Savard Feb 06 '15 at 15:34
  • 1
    Indenting a second statement in an `if` without `else` or an `else` with no curly block delimitation is a difficult bug to spot. From the docs: _Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting to add the newly required braces. The compiler cannot catch this sort of error; you'll just get the wrong results._ – Voicu Feb 06 '15 at 15:39
0

Both those options you have presented aren't as good as two alternatives.

Seeing as you directly exit the loop after a simple comparison then the best option is:

while (a < 5 && a != 3) {
    a++;
}

This is because you need to check both conditions before executing the body, and you don't need to do anything special when exiting the loop.

However, if you need to do need a bit of special logic when a certain condition is hit then you should use a while true loop and breaks.

while (true) {
    if (a >= 5) {
        break; // nothing special, just exit
    } else if (a == 3) {
        a *= 2; // double a before exiting loop
        break;
    }
    a++;
}

The while (true) shows that the only way to exit the loop is with a break, so the programmer should keep an eye out for them. The breaks should also be grouped together at the top of the loop body, so they act as guards preventing the loop body from being executed if their condition is hit.

Dunes
  • 37,291
  • 7
  • 81
  • 97
0

I would choose the break statement since:

  • Code is more clean
  • No need for extra code declarations
  • Debug the code is easier
  • It's common to mess with a lot of flags declared on the condition. You will not want to get a lot of nested conditions on the same line.

There is also exist the continue keyword that will let you to skip parts of the code if necessary.

Misael P
  • 387
  • 1
  • 4
  • 10