Java 如何中断多个 foreach 循环?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/551578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:08:00  来源:igfitidea点击:

How do I break multiple foreach loops?

javarefactoringforeach

提问by royalghost

I have four foreach loops that iterate through the collections and based on a condition do something.

我有四个 foreach 循环,它们遍历集合并根据条件执行某些操作。

Here is the code that I am writing now:

这是我现在正在编写的代码:

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

The main object (objects in the code) comes from a third-party provider SDK, so I cannot change anything on that portion. I want to ask the Stack Overflow community if there is a better approach to break all the four foreach loops. Or if there is any other way to refactor this code to make it more readable and maintainable.

主要对象(代码中的对象)来自第三方提供程序 SDK,因此我无法更改该部分的任何内容。我想问 Stack Overflow 社区是否有更好的方法来打破所有四个 foreach 循环。或者是否有任何其他方法可以重构此代码以使其更具可读性和可维护性。

采纳答案by Luke Woodward

Use a label on the outermost loop, and include this label in the breakstatement when you want to jump out of all the loops. In the example below, I've modified your code to use the label OUTERMOST:

在最外层循环上使用标签,并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

回答by dwc

Throw an exception and catch it outside the loops? Use something that's "considered harmful?"

抛出异常并在循环外捕获它?使用“被认为有害”的东西?

It's a bit funny when computer science paints itself into a corner ;-)

当计算机科学把自己画成一个角落时,这有点好笑;-)

回答by John Leidegren

One way to break, or collapse several statements (actually stack frames) is to throw an exception but this is not recommended because it really expensive for the run-time to unwind the stack and it could lead to really nasty difficult to debug undefined behavior, (keep this in mind).

中断或折叠多个语句(实际上是堆栈帧)的一种方法是抛出异常,但不建议这样做,因为运行时展开堆栈非常昂贵,并且可能导致调试未定义行为非常困难, (记住这一点)。

Otherwise, what I recommend, rewrite that code to be able to break out of the loop in a graceful manner. If you cant change this code in any other way, well then you'll have to result to exceptions...

否则,我建议,重写该代码以便能够以优雅的方式跳出循环。如果您不能以任何其他方式更改此代码,那么您将不得不导致异常...

回答by Alex Reitbort

Extract all the loops into the function and use return.

将所有循环提取到函数中并使用 return。

回答by Pierre

You could use a labeled break statement. This kind of break terminates an outer statement

您可以使用带标签的 break 语句。这种中断终止外部语句

See The break Statement

请参阅break 语句

回答by joel.neely

The straightforward solution is to put the entire search process in a method and returnas soon as you have an answer.

直接的解决方案是将整个搜索过程放在一个方法中,return一旦你有了答案。

However, the abstract form of your sample code leaves some other possibilities in question. For instance, is there a way to "index" some of the content (e.g. using Mapinstances) so that you don't have to use brute-force loops?

但是,示例代码的抽象形式留下了一些其他可能性的问题。例如,有没有办法“索引”某些内容(例如使用Map实例),这样您就不必使用强力循环?

回答by ChrisW

Apart from the fact that Java supports labelled break, see also Is it possible to exit a for before time in C++, if an ending condition is reached?which is a similar question with some other relevent solutions.

除了 Java 支持带标签的中断这一事实外,另请参阅如果达到结束条件,是否可以在 C++ 中退出 for before time?这是一个与其他一些相关解决方案类似的问题。

回答by Bill the Lizard

See the Branching Statements Java Tutorialfor the easiest way, using a label. You can label any or all of the for loops, then use breakor continuein conjunction with those labels.

有关使用标签的最简单方法,请参阅分支语句 Java 教程。您可以标记任何或所有 for 循环,然后使用breakcontinue与这些标签结合使用。

An alternative to using labels is to use returninstead. Just refactor your code into a method call to bypass the need to use labels at all.

使用标签的替代方法是使用return。只需将您的代码重构为方法调用即可完全绕过使用标签的需要。

回答by Esko

Your example is rather generic so it's hard to say what's going on but I'm getting such a a strong code smell from the code you provided that I'm forced to think there has to be another way to do the thing entirely, most likely through refactoring the actual data structure to something more meaningful.

您的示例相当通用,因此很难说发生了什么,但是我从您提供的代码中获得了如此强烈的代码气味,以至于我不得不认为必须有另一种方法来完全完成这件事,最有可能通过将实际数据结构重构为更有意义的东西。

What kind of list objectsis? What other (most likely important)data it contains? If it's not too much of a hassle, I'd appreciate if you provided more relevant code since the refactorer in me is getting all giddy just from seeing that pile of loops.

什么样的清单objects?它包含哪些其他(最可能重要的)数据?如果不是太麻烦,如果您提供更多相关代码,我将不胜感激,因为我的重构者只是看到那堆循环就头晕目眩。