我有一个这样的嵌套循环构造:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             break; // Breaks out of the inner loop
         }
    }
}

现在我怎样才能打破这两个循环?我已经研究过类似的问题,但没有一个与Java相关。我无法应用这些解决方案,因为大多数人都使用goto。

我不想将内部循环放在不同的方法中。

我不想返回循环。当中断时,我完成了循环块的执行。


当前回答

可以使用临时变量:

boolean outerBreak = false;
for (Type type : types) {
   if(outerBreak) break;
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             outerBreak = true;
             break; // Breaks out of the inner loop
         }
    }
}

根据您的功能,您也可以从内部循环退出/返回:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             return;
         }
    }
}

其他回答

使用函数:

public void doSomething(List<Type> types, List<Type> types2){
  for(Type t1 : types){
    for (Type t : types2) {
      if (some condition) {
         // Do something and return...
         return;
      }
    }
  }
}

使用标签。

INNER:for(int j = 0; j < numbers.length; j++) {
    System.out.println("Even number: " + i + ", break  from INNER label");
    break INNER;
}

请参阅本文

演示中断、继续和标签:

Java关键字break和continue具有默认值。这是“最近的循环”,今天,在使用了几年Java之后,我终于明白了!

它似乎很少使用,但很有用。

import org.junit.Test;

/**
 * Created by cui on 17-5-4.
 */

public class BranchLabel {
    @Test
    public void test() {
        System.out.println("testBreak");
        testBreak();

        System.out.println("testBreakLabel");
        testBreakLabel();

        System.out.println("testContinue");
        testContinue();
        System.out.println("testContinueLabel");
        testContinueLabel();
    }

    /**
     testBreak
     a=0,b=0
     a=0,b=1
     a=1,b=0
     a=1,b=1
     a=2,b=0
     a=2,b=1
     a=3,b=0
     a=3,b=1
     a=4,b=0
     a=4,b=1
     */
    public void testBreak() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    break;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testContinue
     a=0,b=0
     a=0,b=1
     a=0,b=3
     a=0,b=4
     a=1,b=0
     a=1,b=1
     a=1,b=3
     a=1,b=4
     a=2,b=0
     a=2,b=1
     a=2,b=3
     a=2,b=4
     a=3,b=0
     a=3,b=1
     a=3,b=3
     a=3,b=4
     a=4,b=0
     a=4,b=1
     a=4,b=3
     a=4,b=4
     */
    public void testContinue() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    continue;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testBreakLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     * */
    public void testBreakLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        break anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }

    /**
     testContinueLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     a=1,b=0,c=0
     a=1,b=0,c=1
     a=2,b=0,c=0
     a=2,b=0,c=1
     a=3,b=0,c=0
     a=3,b=0,c=1
     a=4,b=0,c=0
     a=4,b=0,c=1
     */
    public void testContinueLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        continue anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }
}

通常在这种情况下,它属于更有意义的逻辑范围,比如说搜索或处理一些迭代的“for”对象,所以我通常使用函数方法:

public Object searching(Object[] types) { // Or manipulating
    List<Object> typesReferences = new ArrayList<Object>();
    List<Object> typesReferences2 = new ArrayList<Object>();

    for (Object type : typesReferences) {
        Object o = getByCriterion(typesReferences2, type);
        if(o != null) return o;
    }
    return null;
}

private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
    for (Object typeReference : typesReferences2) {
        if(typeReference.equals(criterion)) {
             // here comes other complex or specific logic || typeReference.equals(new Object())
             return typeReference;
        }
    }
    return null;
}

主要缺点:

大约多出两行计算周期的消耗更多,这意味着从算法角度来看,计算速度更慢更多的打字工作

优点:

由于功能粒度,关注点分离的比率更高更高的重复使用率和控制搜索/操作逻辑这些方法不长,因此更紧凑,更容易理解更高的可读性

所以它只是通过一种不同的方法来处理这个案件。

基本上是问这个问题的作者:你对这种方法有什么看法?

我从不使用标签。这似乎是一种不好的做法。我会这样做:

boolean finished = false;
for (int i = 0; i < 5 && !finished; i++) {
    for (int j = 0; j < 5; j++) {
        if (i * j > 6) {
            finished = true;
            break;
        }
    }
}