【问题标题】:Exiting a loop in Java在 Java 中退出循环
【发布时间】:2011-03-09 13:16:16
【问题描述】:

我正在使用 Java,但我想这个问题适用于任何语言。我只是想问一下,使用我在循环内切换的布尔值退出循环还是只使用 break 是更好的做法;

例如,我只是在编写一个方法来获取国际象棋皇后的有效走法。

private static final int[][] DIRS = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}};

public Vector<Move> getValidMoves() {
    Vector<Move> validMoves = new Vector<Move>();

    for (int i = 0; i < DIRS.length; i++) {
        boolean stopped = false;
        int newX = x + DIRS[i][0];
        int newY = y + DIRS[i][1];
        while (!stopped && newX >= 0 && newX < 8 && newY >= 0 && newY < 8) {
            if (board[newX][newY] == null) {
                validMoves.add(new Move(x, y, newX, newY));
                newX += DIRS[i][0];
                newY += DIRS[i][1];
            } else {
                if (board[newX][newY].getColour() == colour) {
                    stopped = true;
                } else {
                    validMoves.add(new Move(x, y, newX, newY));
                    stopped = true;
                }
            }
        }
    }

    return validMoves;
}

如果我使用 break 退出 while 循环;而不是像我一样将stopped设置为true,我的理解是它运行效率更高,但不是最好的代码风格。

【问题讨论】:

  • 查看您的女王代码,我想说您需要担心的不仅仅是一个中断语句。例如,如果您不需要线程安全的数据结构,请尽量避免使用 Vector(使用 ArrayList 代替),尝试将更多逻辑封装到对象中(例如测试坐标是否在棋盘上,以及替换幻数,例如“ 8")
  • 好的,感谢您的提示。我会考虑的。

标签: java coding-style


【解决方案1】:

break 存在的唯一原因是退出循环,我想不出更好的方法来做到这一点。

【讨论】:

  • 正确!我一直在休息。也就是说,如果不需要更复杂的话。
  • 我想指出,break 也与 switch 一起使用 ^^
【解决方案2】:

就性能而言,这并不重要,您在堆栈上分配 1 个布尔值并在每次循环迭代时添加 1 个比较,因此无需担心。

这主要取决于您是否要在退出之前完成循环代码的其余部分。 Break 将立即退出,设置一个布尔值将等待下一次迭代,然后停止。

如果你不需要完成循环迭代,你的代码如果使用break会更容易阅读

【讨论】:

  • 因为它什么都不做,只是在设置后进入下一个迭代,我猜想打破它。感谢 Johan Sjöberg 和 MarvinLabs 的快速回复。
  • 在这种情况下,是的,我会break
  • 我同意。我曾经害怕 break 关键字。出于某种原因,我将它与糟糕的编程风格联系在一起。这看起来很“残酷”,因为它只是“打破”了循环,如果它“打破”了它,那不是糟糕的设计吗?毕竟一切都应该“流动”。事实证明,break是一个非常优雅的解决方案。我花了几年时间才看到这一点:)
【解决方案3】:

由于这里使用布尔变量对性能影响不大,这是关于可读性的。有些人认为使用 break 语句会降低代码的可读性,原因有两个。

一是在使用break语句时,用户有时无法顺序读取代码(需要跳转读取)。这可能会造成混淆,因为读者需要确定 break 语句将下一个操作带到哪里。

另一件事是,使用变量作为停止条件有助于读者理解如果您有意义地命名变量,它为什么会停止。例如,如果您使用 isEmpty 布尔变量作为停止条件,很明显循环已经停止,因为任何内容都是空的。

我不反对使用 break 语句,但我认为你应该做的是让它尽可能可读。

【讨论】:

    【解决方案4】:

    我建议你做你认为最清楚的事情。恕我直言,对于嵌套循环,使用布尔值可能更清晰,但对于简单循环,使用标志是不必要的冗长。

    while (0 <= newX && newX < 8 && 0 <= newY && newY < 8) {
        if (board[newX][newY] == null) {
            validMoves.add(new Move(x, y, newX, newY));
            newX += DIRS[i][0];
            newY += DIRS[i][1];
        } else {
            if (board[newX][newY].getColour() != colour) 
                validMoves.add(new Move(x, y, newX, newY));
            break;
        }
    }
    

    【讨论】:

      【解决方案5】:

      一定要使用break。这就是关键字的用途,它生成更简洁的代码,不会让阅读您的代码的人想知道循环中的“停止”来自哪里,并且可能更快。

      【讨论】:

      • 为什么说它可能更快?
      • @davin:在第二次迭代后中断(例如)可以说比其余数百次迭代要快......并不是说它会更快不超过 0.01 秒,但仍然如此。
      • @BoltClock,显然继续无用的迭代比退出要慢(保存检查特定条件本身需要很长时间的极端情况)。在我看来,这里的主张是使用break 通常比使用布尔退出条件退出要快。我质疑这种说法。
      • 如果(条件)中断;将导致 CMP-JMP 序列,而 while(flag){if(condition) flag = true;} 至少会产生在堆栈上推送/弹出额外变量的额外开销。变量的范围超出了块,因此编译器不能轻易跳过它,“因为它无论如何都没有被使用”。最重要的是,根据编译器的优化能力,生成的代码可能比简单的 CMP-JMP 更接近 CMP-STORE-JMP-FETCH-CMP-JMP。它永远不会更快,但可能会慢一点。然而,更重要的是,它更难阅读。
      • 哦,天哪...我刚刚通过错误地编写上面的示例证明了我的观点...当然它必须是 while(!flag){if(condition) flag = true; }。看,这就是为什么 break 更优越的原因,通过使用正确的关键字,首先可以避免这种愚蠢的错字。如果语言提供清晰简洁的内容,复杂性就不好。
      【解决方案6】:

      取决于您与谁交谈。我有一位大学教授发誓他会射杀任何没有通过正常的表达式检查退出控制结构(例如循环)的学生。

      但是,我已经看到,尽管这可能是“有纪律的”,但有时还是希望尽早退出循环或其他控制结构。考虑到这一点,我说“去吧”。您仍然可以遵守纪律并拥有没有意外行为的可读代码并提前退出(只要该退出是离开该结构的正当理由。

      【讨论】:

        【解决方案7】:

        这正是语言中有 break 的原因。我会用它。

        【讨论】:

          【解决方案8】:

          和上面提到的用户一样,一定要使用break。退出循环就是它的用途。

          【讨论】:

            【解决方案9】:

            一个似乎还没有提出的观点:

            在 Java 中(但不限于此),使用 break 退出嵌套循环将比在每个级别中嵌套相同的条件优雅。它还将使代码更易于维护。

            此外,它可以使循环的逻辑更加简单,因为一旦你遇到一个中断条件,你就可以采取行动,而不是继续执行代码。这也促进了循环体内的模块化。

            【讨论】:

              【解决方案10】:

              您可能想从 oracle 网页阅读 break 的用法

              Branching Statements Tutorial

              使用 Break 退出循环是一种很好的做法。那么是否使用它取决于您。

              现在,如果您想提高代码的可读性和灵活性,可以考虑将复杂的循环分解为函数。

              【讨论】:

                猜你喜欢
                • 2015-01-18
                • 2011-12-18
                • 2020-09-24
                • 2015-02-28
                • 1970-01-01
                • 2016-09-20
                • 1970-01-01
                • 1970-01-01
                • 2016-02-27
                相关资源
                最近更新 更多