Java'break'语句有时不起作用,为什么?

时间:2017-05-19 08:34:04

标签: java while-loop break

我有以下方法:

public int quickFind (int[] nums, int lo, int hi) {
    if (lo >= hi)
        return -1;

    int gard = nums[lo];
    int i = lo + 1, j = hi + 1;

    while (true) {

        while (nums[++i] < gard) {
            if (i == hi) {
                System.out.println("break   " + i + " / " + hi + " ->" + (i == hi));
                break;
            }
        }

        while (gard < nums[--j]) {
            if (j == lo)
                break;
        }

        if (i > j)
            break;

        if (nums[i] == gard)
            return nums[i];
        if (nums[j] == gard) 
            return nums[j];

        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    nums[lo] = nums[j];
    nums[j] = gard;

    return 1 + quickFind(nums, lo, j - 1) + quickFind(nums, j + 1, hi);
}

我建立了一个随机数组,例如[3 4 2 4 1 5]来测试我的方法。但是,似乎第13行中的break语句不起作用,抛出异常消息&#34; java.lang.ArrayIndexOutOfBoundsException:6&#34;。

所以,我设置断点来调试第13行的break语句和第11行的if条件。我无法相信自己的眼睛。 &#39;休息&#39;不起作用。

有趣的是,它并非总是发生。有时我的程序运行正常,有时会出现上述问题。就像一个question that has been raised

谁能告诉我为什么?为什么会这样?

3 个答案:

答案 0 :(得分:5)

无向break只会突破显示的最内层循环。例如,break此处:

while (condition1) {
    while (condition2) {
        if (condition3) {
            break;
        }
    }
}

...突破while (condition2)而不是while (condition1)

如果你需要突破外循环,它可能值得做一些重构,但是如果你真的需要你可以标记外部循环然后使用定向中断:

    outer: while (condition1) {
//  ^^^^^----- the label
        while (condition2) {
            if (condition3) {
                break outer;
// Directed ----------^^^^^
            }
        }
    }

break while (condition1)将会突破while (condition2)(根据定义,它会突破breaks)。

这里是该代码中public int quickFind (int[] nums, int lo, int hi) { if (lo >= hi) return -1; int gard = nums[lo]; int i = lo + 1, j = hi + 1; while (true) { // *** Loop 1 while (nums[++i] < gard) { // *** Loop 2 if (i == hi) { System.out.println("break " + i + " / " + hi + " ->" + (i == hi)); break; // *** Breaks loop 2 } } while (gard < nums[--j]) { // *** Loop 3 if (j == lo) break; // *** Breaks loop 3 } if (i > j) break; // *** Breaks loop 1 if (nums[i] == gard) return nums[i]; if (nums[j] == gard) return nums[j]; int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } nums[lo] = nums[j]; nums[j] = gard; return 1 + quickFind(nums, lo, j - 1) + quickFind(nums, j + 1, hi); } 的细分(没有双关语)以及它们中断的循环:

pdfDoc.getPage(num).then(function(page) {
      var viewport = page.getViewport(scale);
      canvas.height = viewport.height;
      canvas.width = viewport.width;
...

该函数是递归的,并且调试递归函数可能有点令人困惑,虽然递归不是在这些内部循环中的任何一个,所以我不希望它因素在那里。

答案 1 :(得分:1)

因为在某些情况下,您break退出内部while循环,而在其他情况下,您只是break退出外部while循环。基本上他们被称为不同的范围。

答案 2 :(得分:0)

当hi = 6,lo = 5时,不会检查条件(i == hi),但抛出OutOfBoundsException请在调试器中检查它们的值

  while (nums[++i] < gard) {
        if (i == hi) {
            System.out.println("break   " + i + " / " + hi + " ->" + (i == hi));
            break;
        }
    }