【问题标题】:how can we go out from 4 inner for loops?我们如何从 4 个内部 for 循环中退出?
【发布时间】:2010-11-18 10:55:58
【问题描述】:

嗨 我是java初学者,我的程序有4个for循环: 我的程序是这样工作的,如果 btrue ,则该元素将从 pointList 中删除,n 将是 n-- 并且我想从所有 for 循环中退出并从第一个 for 循环中再次出现所以l 将是l++,我该怎么做?有break语句?

for (int l = 0; l < n; l++) {
  for (int i = 1; i < (n - 2); i++) {
      for (int j = i + 1; j < (n - 1); j++) {
          for (int k = j + 1; k < n; k++) {
              if (l != i && l != j && l != k) {
                  boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                  System.out.println(b);
                  if (b == true) {
                      pointList.remove(pointList.get(l);
                      n--;
                      break;
                  }
                  else
                      System.out.println(b);
              }
           }
       }
    }
}

【问题讨论】:

  • 天哪!真的有必要这样走过吗?请avoid级联循环..
  • 也许你可以用几句话描述你想做什么? “如果 b 为真,则删除第 l 项”。您的代码包含语法错误。请修复它,并澄清您的问题。
  • 您似乎正在尝试查找符合某些条件的 4 个元素。如果您解释了标准是什么,也许我们可以建议一种更简单的方法来做同样的事情。例如也许首先对列表进行排序可能会简化循环。
  • +1 - 几乎没用的链接,但我还是同意这个建议。

标签: java for-loop label break labelled-break


【解决方案1】:

您可以将带标签的中断用作:

      for (int l = 0; l < n; l++) {
 foo:    for (int i = 1; i < (n - 2); i++) {
            for (int j = i + 1; j < (n - 1); j++) {
                for (int k = j + 1; k < n; k++) {
                    if (l != i && l != j && l != k) {
                        boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                        System.out.println(b);
                        if (b == true) {
                            pointList.remove(pointList.get(l);
                            n--;
                            break foo;
                        }
                        else
                            System.out.println(b);
                    }

                }

            }
        }
    }

【讨论】:

  • 它只会中断最后三个 for 循环,然后它会从第一个循环开始并进入这三个 for 循环?
  • 我想你可以认为任何分支语句都是“变相的 goto”。但它们都有其局限性和用途。实际上,甚至 goto 本身也是如此(状态机是没有它的 PITA)。
  • 没有事件知道 java 中有标记的中断:D
【解决方案2】:

在循环中,break 语句终止内部循环,而continue 跳到下一次迭代。为了让这两个语句在与内部语句不同的循环上工作,您需要使用labels。这样的事情应该可以工作:

outerloop:      
        for (int l = 0; l < n; l++) {
            for (int i = 1; i < (n - 2); i++) {
                for (int j = i + 1; j < (n - 1); j++) {
                    for (int k = j + 1; k < n; k++) {
                        if (l != i && l != j && l != k) {
                            boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                            System.out.println(b);
                            if (b == true) {
                                pointList.remove(pointList.get(l);
                                n--;
                                continue outerloop;
                            }
                            else
                                System.out.println(b);
                        }

                    }

                }
            }
        }

【讨论】:

    【解决方案3】:

    查看带标签的 break 语句

    例如这里:Branching Statements

    【讨论】:

      【解决方案4】:
      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
      
      【解决方案5】:

      使用带标签的循环

      for (int l = 0; l < n; l++) {
          loopa:
          for (int i = 1; i < (n - 2); i++) {
              for (int j = i + 1; j < (n - 1); j++) {
                  for (int k = j + 1; k < n; k++) {
                      if (l != i && l != j && l != k) {
                          boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
                          System.out.println(b);
                          if (b == true) {
                              pointList.remove(pointList.get(l);
                              n--;
                              break loopa;
                          }
                          else
                              System.out.println(b);
                      }
      
                  }
      
              }
          }
      }
      

      然后从标记的循环中中断

      【讨论】:

      • 它只会中断最后三个 for 循环,然后它会从第一个循环开始并进入这三个 for 循环?
      • 功能上等同于 Brain。因为它将进入最外层循环的下一次迭代
      【解决方案6】:
      again:
      for (int l = 0; l < n; l++) {
              for (int i = 1; i < (n - 2); i++) {
                  for (int j = i + 1; j < (n - 1); j++) {
                      for (int k = j + 1; k < n; k++) {
                          if (l != i && l != j && l != k) {
                              boolean b = isOK(pointList.get(l), pointList.get(i),  pointList.get(j), pointList.get(k));
                              System.out.println(b);
                              if (b == true) {
                                  pointList.remove(pointList.get(l);
                                  n--;
                                  break again;
                              }
                              else
                                  System.out.println(b);
                          }
      
                      }
      
                  }
              }
          }
      

      【讨论】:

        【解决方案7】:

        我同意所有其他答案。但是,我想指出exit 的替代方法是将该代码放入自己的例程中并使用return 语句来打破整个过程。您的四重嵌套循环本身就非常复杂,以至于它可能无论如何都应该放在自己的例程中。

        我从事的 DoD 工作要求任何一个例程的cyclomatic complexity 不超过 6(有一些例外)。仅这一系列循环就是 4 个。如果您找不到更简单的方法来执行此操作,那么您真的应该将它们扔进自己的例程中,以保持必须维护此代码的可怜的笨蛋的理智。

        【讨论】:

          【解决方案8】:

          第一个“快速而肮脏”的解决方案是使用stay_into_loops 变量并修改for 循环,例如:

           boolean stay_into_loops = true
           // here goes the first for loop
           for (int i = 1; i < (n - 2) && stay_into_loops ; i++) {
                      for (int j = i + 1; j < (n - 1) && stay_into_loops ; j++) {
                          for (int k = j + 1; k < n && stay_into_loops ; k++) {
                              if (l != i && l != j && l != k) {
                                  boolean b = isOK(pointList.get(l), `pointList.get(i), pointList.get(j), pointList.get(k));`
                                  System.out.println(b);
                                  if (b == true) {
                                      pointList.remove(pointList.get(l);
                                      n--;
                                      stay_into_loops = false;
                                      break;
          

          但是,当您遇到此类情况时,通常会产生代码异味。考虑重构代码,因为这会在某些时候升级为一团糟。

          【讨论】:

            【解决方案9】:

            在每个内部 for 循环中为自己创建一个出口。
            这是一个快速且无痛的解决方案。

              bool breakout;
              for (int l = 0; l < n; l++) 
              {
                    breakout = false;
                    for (int i = 1; i < (n - 2) && !breakout; i++)
                        for (int j = i + 1; j < (n - 1) && !breakout; j++)
                            for (int k = j + 1; k < n && !breakout; k++)
                            {
                                if(b == true)
                                    breakout = true;                            
                            }
              }
            

            所以你看到 breakout 布尔值是你退出每个内部循环的票,因为它会在每个 for 声明中被检查。 并且每次第一个 for 迭代时都会重置。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-10
              • 1970-01-01
              • 2011-01-22
              • 2022-01-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多