Answers:
像其他答复者一样,我绝对希望将循环放入另一种方法中,此时您可以返回以完全停止迭代。该答案仅显示了如何满足问题中的要求。
您可以将break
标签与外循环一起使用。例如:
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
打印:
0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done
break
。即使这样,异常还是另一个众所周知的异常(对不起)。但是,如果它不是很明显,我仍然会对此感到不满意(小循环,如果标签/中断仍然不够明显,则会发出警告注释)。
outerloop
是一个标签。我不知道您到底尝试了什么代码,但是答案中的代码可以编译并正常运行。
从技术上讲,正确的答案是标记外循环。在实践中,如果您想在内部循环中的任何点退出,那么最好将代码外部化为一个方法(如果需要,可以使用静态方法),然后再对其进行调用。
这将提高可读性。
该代码将变成这样:
private static String search(...)
{
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
return search;
}
}
}
return null;
}
匹配示例以接受答案:
public class Test {
public static void main(String[] args) {
loop();
System.out.println("Done");
}
public static void loop() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
return;
}
System.out.println(i + " " + j);
}
}
}
}
loop
方法之外,然后从方法返回以继续。
您可以在循环周围使用命名块:
search: {
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break search;
}
}
}
}
name: if(...){...}
使命名条件得以实现?:)
for
直接标记相比,此构造具有很大的优势。}
仅当从未满足条件时,才可以在将要执行的最后一个代码之前添加代码。
我从不使用标签。进入这似乎是一个坏习惯。这是我会做的:
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;
}
}
}
&& !finished
代替|| !finished
吗?那么为什么还要使用break
而不使用&& !finished
内部循环呢?
break
能够任意退出循环。如果该代码if
块之后有代码,则可以break
在代码执行之前。但是你是对的&&
。固定它。
您可以使用一个临时变量:
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;
}
}
}
如果您不喜欢break
s和goto
s,则可以使用“传统” for循环而不是for-in,并带有额外的中止条件:
int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
for (b = 0; b < 10 && !abort; b++) {
if (condition) {
doSomeThing();
abort = true;
}
}
}
我需要做类似的事情,但是我选择不使用增强的for循环来做。
int s = type.size();
for (int i = 0; i < s; i++) {
for (int j = 0; j < t.size(); j++) {
if (condition) {
// do stuff after which you want
// to completely break out of both loops
s = 0; // enables the _main_ loop to terminate
break;
}
}
}
s
为小于的值,i
或者更改i
为大于或等于的值s
,两者都可以解决问题。您对更改是正确的s
,因为它可以在以后的其他地方使用,但是更改i
不会造成危害,只需确保第一个for
不会继续循环即可。
Java 8 Stream
解决方案:
List<Type> types1 = ...
List<Type> types2 = ...
types1.stream()
.flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
.filter(types -> /**some condition**/)
.findFirst()
.ifPresent(types -> /**do something**/);
通常,在这种情况下,它会进入更有意义的逻辑范围,例如,对某些迭代的“ 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;
}
主要缺点:
优点:
因此,它只是通过不同的方法来处理案件。
基本上是这个问题的作者提出的一个问题:您如何看待这种方法?
您可以不使用任何label:和标志而中断所有循环。
这只是棘手的解决方案。
这里的condition1是用于中断循环K和J的条件。而condition2是用于中断循环K,J和I的条件。
例如:
public class BreakTesting {
public static void main(String[] args) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = 0; k < 9; k++) {
if (condition1) {
System.out.println("Breaking from Loop K and J");
k = 9;
j = 9;
}
if (condition2) {
System.out.println("Breaking from Loop K, J and I");
k = 9;
j = 9;
i = 9;
}
}
}
}
System.out.println("End of I , J , K");
}
}
(int k = 0; k < 10; k++)
而没有将所有固定k = 9
为k = 10
。您可能会陷入无限循环。
标记中断概念用于在Java中中断嵌套循环,通过使用标记中断,您可以在任何位置中断循环嵌套。范例1:
loop1:
for(int i= 0; i<6; i++){
for(int j=0; j<5; j++){
if(i==3)
break loop1;
}
}
假设有3个循环,并且您想终止loop3:示例2:
loop3:
for(int i= 0; i<6; i++){
loop2:
for(int k= 0; k<6; k++){
loop1:
for(int j=0; j<5; j++){
if(i==3)
break loop3;
}
}
}
最佳简便方法
outerloop:
for(int i=0; i<10; i++){
// here we can break Outer loop by
break outerloop;
innerloop:
for(int i=0; i<10; i++){
// here we can break innerloop by
break innerloop;
}
}
使用标签。
INNER:for(int j = 0; j < numbers.length; j++) {
System.out.println("Even number: " + i + ", break from INNER label");
break INNER;
}
参考这篇文章
另一个解决方案,没有示例提及(实际上在产品代码中有效)。
try {
for (Type type : types) {
for (Type t : types2) {
if (some condition #1) {
// Do something and break the loop.
throw new BreakLoopException();
}
}
}
}
catch (BreakLoopException e) {
// Do something on look breaking.
}
当然BreakLoopException
应该是内部的,私有的并且使用无堆栈跟踪来加速:
private static class BreakLoopException extends Exception {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[0];
}
}
for (int j = 0; j < 5; j++) //inner loop
应该用代替
for (int j = 0; j < 5 && !exitloops; j++)
。
在这种情况下,如果condition为,则应退出完整的嵌套循环True
。但是如果我们exitloops
只用上 loop
for (int i = 0; i < 5 && !exitloops; i++) //upper loop
然后,内部循环将继续,因为没有多余的标志通知该内部循环退出。
例如:如果
i = 3
和j=2
然后条件false
。但在内部循环的下一个迭代j=3
,然后条件(i*j)
成为9
这true
可是内部循环将持续到j
成为5
。
因此,它也必须用于exitloops
内部循环。
boolean exitloops = false;
for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true.
for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement.
if (i * j > 6) {
exitloops = true;
System.out.println("Inner loop still Continues For i * j is => "+i*j);
break;
}
System.out.println(i*j);
}
}
如果是新实现,则可以尝试将逻辑重写为if-else_if-else语句。
while(keep_going) {
if(keep_going && condition_one_holds) {
// Code
}
if(keep_going && condition_two_holds) {
// Code
}
if(keep_going && condition_three_holds) {
// Code
}
if(keep_going && something_goes_really_bad) {
keep_going=false;
}
if(keep_going && condition_four_holds) {
// Code
}
if(keep_going && condition_five_holds) {
// Code
}
}
否则,您可以尝试在发生特殊情况时设置一个标志,并在每个循环条件中检查该标志。
something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
// Code, things happen
while(something else && !something_bad_has_happened){
// Lots of code, things happens
if(something happened){
-> Then control should be returned ->
something_bad_has_happened=true;
continue;
}
}
if(something_bad_has_happened) { // The things below will not be executed
continue;
}
// Other things may happen here as well, but they will not be executed
// once control is returned from the inner cycle.
}
这里!因此,虽然简单的中断不起作用,但可以使用来使其起作用continue
。
如果您只是将逻辑从一种编程语言移植到Java,而只是想使事情正常运行,则可以尝试使用标签。
演示的break
,continue
和label
:
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);
}
}
}
}
}
您可以执行以下操作:
将局部变量设置为 false
true
要中断时,请在第一个循环中设置该变量
那么您可以在外循环中检查是否设置了条件,然后再从外循环中断开。
boolean isBreakNeeded = false;
for (int i = 0; i < some.length; i++) {
for (int j = 0; j < some.lengthasWell; j++) {
//want to set variable if (){
isBreakNeeded = true;
break;
}
if (isBreakNeeded) {
break; //will make you break from the outer loop as well
}
}
在某些情况下,我们可以while
在这里有效地使用循环。
Random rand = new Random();
// Just an example
for (int k = 0; k < 10; ++k) {
int count = 0;
while (!(rand.nextInt(200) == 100)) {
count++;
}
results[k] = count;
}
Java没有像C ++一样具有goto功能。但仍然goto
是Java中的保留关键字。他们可能会在将来实施它。对于您的问题,答案是Java中有一个称为label的东西,您可以在其中应用continue
and break
语句。查找下面的代码:
public static void main(String ...args) {
outerLoop: for(int i=0;i<10;i++) {
for(int j=10;j>0;j--) {
System.out.println(i+" "+j);
if(i==j) {
System.out.println("Condition Fulfilled");
break outerLoop;
}
}
}
System.out.println("Got out of the outer loop");
}
甚至为外循环创建一个标志并在每次执行内循环后检查是否可以解决问题。
像这样:
for (Type type : types) {
boolean flag=false;
for (Type t : types2) {
if (some condition) {
// Do something and break...
flag=true;
break; // Breaks out of the inner loop
}
}
if(flag)
break;
}