【问题标题】:Breaking 2 nested loops "at once" [duplicate]“一次”打破2个嵌套循环[重复]
【发布时间】:2014-06-11 04:16:17
【问题描述】:

请看下面的代码(Java)

 while((str=br.readLine())!=null)
        {
            int tempCounter=0;

            for(int i=0;i<str.length();i=i+3)
            {
                String word = str.substring(i, i+3);
                //  System.out.println(word);
                int insert = db.insert(index, word);
                if(insert<0)
                {
                    break;
                }
                tempCounter++;
            }
            index++;

            System.out.println("Index Updated: "+index);
            System.out.println(String.valueOf("Total words in this run: "+tempCounter));

            if(index==5)
            {
                break;
            }

        }

如果insert 小于0,我需要打破forwhile 循环。我该怎么做?

这里的问题是,如果 insert 小于 0,我需要打破“两个”循环。而且你不能一个接一个地添加 2 个 break 命令,即使有标签。

【问题讨论】:

  • 或者你可以这样做 if(index==5 || insert
  • @AntonH 我不同意这是链接问题的副本。当然,一个可能的答案是“使用标签”,但这个问题并不是直接询问标签。

标签: java for-loop while-loop nested-loops break


【解决方案1】:

+1.. @AntonH.. label 是第一个选项.. 如果您对如何使用 label 感到困惑.. 您可以使用如下布尔变量..

while (...) {

    boolean brk = false;
    for (...) {
        if(insert<0)
        {   brk = true;
            break;
        }
    }
    if(brk)
    {
        break;
    }
}

【讨论】:

    【解决方案2】:
     while((str=br.readLine())!=null)
     {
            int tempCounter=0;
            boolean check = false;
            for(int i=0;i<str.length();i=i+3)
            {
                String word = str.substring(i, i+3);
                //  System.out.println(word);
                int insert = db.insert(index, word);
                if(insert<0)
                {
                    check = true;
                    break;
                }
                tempCounter++;
            }
            index++;
            if(check)
                break;
    
            System.out.println("Index Updated: "+index);
            System.out.println(String.valueOf("Total words in this run: "+tempCounter));
    
            if(index==5)
            {
                break;
            }
    
        }
    

    你可以这样做

    【讨论】:

      【解决方案3】:

      您的问题已经部分回答here。使用 while 循环行前面的标签,例如OUTMOST,那么当insert小于0时,'break OUTMOST'。例如:

      OUTMOST:
          while(someCondition) {
              for(int i = 0; i < someInteger; i++) {
                  if (someOtherCondition)
                      break OUTMOST;
              }
          }
      

      【讨论】:

        【解决方案4】:

        你可以试试这个简单的例子来看看带标签的循环是如何工作的:

        public static void main(String[] args) {
            int i = 0; int j = 0;
            EXIT: for (; i < 10; i++) {
                for (; j < 10; j++) {
                    if (i * j > 50) {
                        break EXIT;
                    }
                }
                j = 0;
            }
            System.out.printf("Finished with i=%s and j=%s\n", i, j);
        
        }
        

        输出:

        Finished with i=6 and j=9
        

        【讨论】:

        • 仅仅因为你可以编写for循环和if不带大括号的语句,并不意味着你应该...跨度>
        • 在我看来,如果单个主体语句出现在同一行,则不必添加大括号(假设您不使用 IDE 的自动格式化,我从不这样做)。但这是另一个话题,对此有许多不同的看法。防御性程序员总是使用大括号,但为了提高可读性,我有时会省略它们(很少)。
        • 我不会认为 for 循环 if 语句和 break 在同一行更具可读性。但是,正如您所说,这是一个意见和个人喜好问题,所以我会放弃这个问题。
        【解决方案5】:

        一种方法是使用异常,具体取决于 db.insert 例程的预期结果。

        简而言之,创建一个新的 EDBInsertionException 异常(一个扩展 Exception 的类)并在您的 for 循环中引发该异常。

        try
        {
        
            while((str=br.readLine())!=null)
            {
                int tempCounter=0;
        
                for(int i=0;i<str.length();i=i+3)
                {
                    String word = str.substring(i, i+3);
                    //  System.out.println(word);
                    int insert = db.insert(index, word);
                    if(insert<0)
                    {
                        throw new EDBInsertionException("No record inserted: " + insert);
                    }
                    tempCounter++;
                }
                index++;
        
                System.out.println("Index Updated: "+index);
                System.out.println(String.valueOf("Total words in this run: "+tempCounter));
        
                if(index==5)
                {
                    break;
                }
        
            }
        }
        catch (EDBInsertionException e)
        {
            // MZ: The database insertion has failed
            log.error(e.getMessage(), e);
        
            // MZ: Supplemental action: Delegate, escalate, rollback, etc           
        }
        

        编辑

        扩展示例以说明(用户)异常的潜在用法。

        【讨论】:

        • 这不是例外的用途。
        • 请详细说明,我认为这是默认工作流的一个例外(无法插入记录,因此会导致预期结果出现异常)。
        • 使用异常作为流控制机制(正在这样做)是不好的做法。如果没有更多的上下文,-1 很可能只是表示I'm done inserting stuff now, carry on,这肯定不是一个例外情况。
        • 当然这取决于 db.insert 命令的预期行为。取决于此,这将或不会是反模式。一般来说,如果插入语句无法引发异常,我希望它会引发异常,但如果代码将其留给调用者,则会出现异常。
        【解决方案6】:

        IMO,例外是不合适的;标签很少见,未来的读者不太可能理解。

        调用KISS 原则,为什么不使用一个额外的标志并增加每个循环中使用的表达式:

        boolean isInsertFail = false;
        
        while((! isInsertFail) && (str=br.readLine())!=null))
                {
                    int tempCounter=0;
        
                    for(int i=0;(! isInsertFail) && i<str.length();i=i+3)
                    {
                        String word = str.substring(i, i+3);
                        //  System.out.println(word);
                        int insert = db.insert(index, word);
                        if(insert<0)
                        {
                            isInsertFail = true;
                        }
                        tempCounter++;
                    }
        
                    if (!isInsertFail) {
                        index++;
        
                        System.out.println("Index Updated: "+index);
                        System.out.println(String.valueOf("Total words in this run: "+tempCounter));
        
                        if(index==5)
                        {
                            break;
                        }
                    }
                }
        

        请注意,在 Eclipse 中,可以单击isInsertFail,语法突出显示应说明其用途。

        【讨论】:

        • 不管怎样,用label 监控上层循环,只破坏子循环会破坏子循环对吗?
        猜你喜欢
        • 2010-10-13
        • 2015-03-03
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2012-01-19
        相关资源
        最近更新 更多