如何在不使用标签的情况下打破嵌套循环
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;
}
}
}
}
你好,这是我的代码。
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;
}
}
}
}