Miljan Rakita
Miljan Rakita

Reputation: 1533

How to break from nested loops without using label's

Hello here is my code.

int counter=0;

    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            System.out.println(++counter);
            if(counter==11)
                break;
        }
    }

My question is how to end both loops when counter is equal to 11 ? In this example i just end the second loop. I know there is a way if i use label's, but is there any other way ? Thanks in advance.

Upvotes: 1

Views: 887

Answers (5)

vikingsteve
vikingsteve

Reputation: 40378

Answer 1

Well, you can do it like this by adding the condition into both for loops.

    for(int i=0;i<5 && counter!=11;i++)
    {
        for(int j=0;j<5 && counter!=11;j++)
        {
            System.out.println(++counter);
        }
    }

But you are violating the DRY principle and likely triggering an IDE / Sonar warning.

Answer 2

Add an exception to your class

private static class LoopDoneException extends Exception { }

Now throw it:

    try {
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<5;j++)
            {
                System.out.println(++counter);
                if (counter == 11) {
                    throw new LoopDoneException();
                }
            }
        }
    } catch (LoopDoneException e) {
        // expected
    }
}

Answer 3

On reflection, I think teh best approach is a break statement referring to the label out.

    out:
    for (int i = 0; i < 5; i++) {
        System.out.println("outer loop");
        for (int j = 0; j < 5; j++) {
            System.out.println("inner loop: " + ++counter);
            if (counter == 11) {
                break out;
            }
        }
    }

Upvotes: 5

daiscog
daiscog

Reputation: 12057

Personally, I don't mind using labels to break loops, but if a style guide proscribes it, one option is to put the loop in its own method and return instead of breaking:

private void doNestedLoop() {
    for (/* outer stuff */) {
        for (/* inner stuff */) {
            if (/* outer should break? */) {
                return;
            }
        }
    }
}

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533482

In Java 8 you can do

IntStream.range(0, 5)
         .flatMap(i -> IntStream.range(i * 5, i*5+5))
         .limit(11)  // instead of a counter
         .forEach(System.out::println);

In Java 7 you can encapsulate it in a method

static void printOneToEleven() {
    int counter = 0;
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (++counter > 11)
                return;
            System.out.println(counter);
        }
    }
}

Upvotes: 0

Sivakumar
Sivakumar

Reputation: 1751

Simply have a flag along with condition in outer loop, initially it was set to false. Once it meets your condition, just set the flag to true. so the outer for loop condition fails and gets out.

boolean isDone = false;
int counter=0;

for(int i=0;i<5 && !isDone; i++)
{
    for(int j=0;j<5;j++)
    {
        System.out.println(++counter);

        if(counter==11){
            isDone = true;
            break;
        }
    }
}

Upvotes: 5

tobias_k
tobias_k

Reputation: 82889

Your outer loop tests whether i < 5, so you could just invalidate that:

int counter=0;
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        System.out.println(++counter);
        if (counter == 11) {
            i = 5; // this will end the outer loop
            break;
        }
    }
}

However, in practice I rather would not do this, but rather use the same condition again in the outer loop, or use a boolean flag. Readability counts!

Also, I think in this case, the use of labels would be perfectly fine and quite readable.

Upvotes: 2

Related Questions