本问题已经有最佳答案,请猛点这里访问。
我有四个foreach循环,它们遍历集合,并根据条件执行一些操作。
这是我现在写的代码:
boolean breakFlag = false;
String valueFromObj2 = null;
String valueFromObj4 = null;
for(Object1 object1: objects){
for(Object2 object2: object1){
// I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
// Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
// Compare with valueFromObj2 to decide either to break all the foreach loop
breakFlag = compareTwoVariable(valueFromObj2, valueFromObj4 );
if(breakFlag){break;}
} // fourth loop ends here
if(breakFlag){break;}
} // third loop ends here
if(breakFlag){break;}
} // second loop ends here
if(breakFlag){break;}
} // first loop ends here
主对象(代码中的对象)来自第三方提供程序SDK,因此我不能更改该部分的任何内容。我想问堆栈溢出社区是否有更好的方法来打破所有四个foreach循环。或者,如果有任何其他方法可以重构此代码,使其更易于阅读和维护。
顺便说一句,这是给不前臂的。
不,for(object o:os)实际上称为foreach或迭代器循环。
原始版本在代码本身中有"foreach"。谢谢编辑。
在最外面的循环上使用一个标签,当您想跳出所有循环时,将这个标签包含在break语句中。在下面的示例中,我修改了您的代码以使用标签OUTERMOST:
String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
for(Object2 object2: object1){
//I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
//Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
//Compare with valueFromObj2 to decide either to break all the foreach loop
if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
break OUTERMOST;
}
}//fourth loop ends here
}//third loop ends here
}//second loop ends here
}//first loop ends here
这是我问题的正确答案。但是,我像其他人建议的那样重构,并将逻辑移到一个小函数中,并使用"返回"。
只有在没有其他解决方案时才使用标签函数。这不是一个好的做法。
将所有循环提取到函数中并使用返回。
如图所示的代码并不好:沿着这些行重构会更好。
这是使用断纸标签的首选方法,除非您知道使用断纸更清晰。
在任意位置引入方法边界是"首选方法"?
最好用标签
可以使用带标签的break语句。这种中断终止了外部语句
参见break语句
您的示例非常通用,所以很难说是怎么回事,但是我从您提供的代码中得到了一种强烈的代码味道,我不得不认为必须有另一种方法来完成这项工作,最有可能的方法是将实际的数据结构重构为更有意义的内容。
什么样的清单objects是?它还包含哪些其他(最可能重要的)数据?如果不是太麻烦的话,我希望您能提供更相关的代码,因为我的重构器看到那堆循环就变得头晕目眩了。
使用一个标签,可以看到最简单的分支语句Java教程。您可以标记任意或所有for循环,然后将break或continue与这些标签一起使用。
使用标签的另一种选择是使用return。只需将代码重构为一个方法调用,就完全不需要使用标签。
中断或折叠多个语句(实际上是堆栈帧)的一种方法是抛出一个异常,但不建议这样做,因为运行时展开堆栈非常昂贵,并且可能导致非常严重的难以调试未定义行为(请记住这一点)。
否则,按照我的建议,重写代码,使其能够以优雅的方式脱离循环。如果您不能以任何其他方式更改此代码,那么您将不得不导致异常…
Java确实支持标签,但它们只能用于Stand和Sturn语句。
除了Java支持标记断言之外,如果达到结束条件,还可以在C++中提前退出AO吗?这是一个与其他相关解决方案类似的问题。
简单的解决方案是将整个搜索过程放入一个方法中,并且在得到答案后立即执行return。
但是,您的示例代码的抽象形式还存在一些其他可能的问题。例如,是否有一种方法可以"索引"某些内容(例如,使用Map个实例),以便不必使用暴力循环?
抛出异常并在循环之外捕获它?使用"有害"的东西?
当计算机科学把自己描绘成一个角落时,有点滑稽;—)
"计算机科学"不是"把自己画成一个角落"。但有时程序员会做出早期的选择或假设,限制他们以后的选择。
我觉得我很有趣。结果可能会有所不同。
结果可能会有所不同。爆笑。