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

Java“break”语句有时不起作用,为什么?,java,while-loop,break,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) {

我有以下方法:

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语句似乎不起作用,并抛出异常消息java.lang.ArrayIndexOutOfBoundsException:6


因此,我设置了断点来调试第13行中的break语句和第11行中的if条件。我简直不敢相信我的眼睛。“休息”不起作用

有趣的是,这种情况并非总是发生。有时我的程序工作正常,有时出现上述问题。就像一个


谁能告诉我为什么?为什么会发生这种情况?

因为在某些情况下,您打破了内部while循环,而在其他情况下,您只是打破了外部while循环。基本上,它们是在不同的范围内被调用的。

无向中断只会从它出现的最内层循环中中断。例如,此处的中断:

…在条件2时中断,但在条件1时不中断

如果需要中断外循环,可能值得进行一些重构,但如果确实需要,可以标记外循环,然后使用定向中断:

    outer: while (condition1) {
//  ^^^^^----- the label
        while (condition2) {
            if (condition3) {
                break outer;
// Directed ----------^^^^^
            }
        }
    }
该中断将同时中断while条件1,根据定义,这意味着它将中断while条件2

下面是一个关于代码中的中断以及它们中断了哪些循环的分解:

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);
}

该函数是递归的,调试递归函数可能会有点混乱,尽管递归不在这两个内部循环中,所以我不希望它在其中发挥作用。

当hi=6、lo=5时,不会检查条件I==hi,但抛出BoundsException请在调试器中检查它们的值

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

我设置断点以调试在第13行中的中断语句,考虑更具体地说明哪一行。另外,您没有告诉我们从该范围观察到的值,特别是在什么组合导致意外行为方面。这对我来说很好。当i==hi时,它从while nums[++i]J中断所迷惑;所以也许你想把它纳入你的答案中[]nums={3,4,2,4,1,5};JDK1.8,Win10
  while (nums[++i] < gard) {
        if (i == hi) {
            System.out.println("break   " + i + " / " + hi + " ->" + (i == hi));
            break;
        }
    }