如何在不使用标签的情况下打破嵌套循环

How to break from nested loops without using label's

你好,这是我的代码。

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;
        }
    }

我的问题是当计数器等于11时如何结束两个循环? 在这个例子中,我只是结束了第二个循环。 我知道如果我使用标签有一种方法,但是还有其他方法吗? 提前致谢。

回答 1

好吧,你可以通过将条件添加到两个 for 循环中来做到这一点。

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

但是你违反了DRY原则并可能触发IDE/声纳警告。

回答2

为您的 class

添加一个例外
private static class LoopDoneException extends Exception { }

现在扔:

    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
    }
}

回答 3

经过深思熟虑,我认为最好的方法是引用标签 out.

break 语句
    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;
            }
        }
    }

您的外循环测试是否 i < 5,因此您可以使它无效:

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;
        }
    }
}

然而,实际上我宁愿不这样做,而是在外循环中再次使用相同的条件,或者使用布尔标志。可读性很重要!

此外,我认为在这种情况下,使用标签会非常好并且非常可读。

在Java8你可以做到

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

在Java7中可以封装在一个方法中

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);
        }
    }
}

只是在外循环中有一个标志和条件,最初它被设置为 false。一旦满足您的条件,只需将标志设置为 true 即可。所以外部 for 循环条件失败并退出。

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;
        }
    }
}

就我个人而言,我不介意使用标签来打破循环,但如果风格指南禁止它,一个选择是将循环放在它自己的方法中并且 return 而不是打破:

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