【问题标题】:Does order of conditions matter with multiple conditions in a while loop?条件顺序是否与 while 循环中的多个条件有关?
【发布时间】:2017-07-20 06:59:22
【问题描述】:

我无法找到这个问题的答案。我正在研究一种插入排序方法,但它无法正确执行:

public static <T extends Comparable<? super T>> void insertionSort(T[] array) {
    int length = array.length;
    T temp;
    for (int i = 1; i < length; i++) { //start of unsorted
        temp = array[i]; //save the element
        int j = i-1;
        while (temp.compareTo(array[j]) < 0 && j >= 0) { // while temp is less than array[j]
            array[j+1] = array[j]; 
            j--;
        } //end of while
        array[j+1] = temp; //as soon as temp is greater than array[j], set array[j] equal to temp
    }
}

这在 while 循环行上返回了一个 ArrayIndexOutOfBoundsException,但是当我将 while 循环中的条件切换到这个时:

while (j >= 0 && temp.compareTo(array[j]) < 0)

成功了。我不认为在Java中while循环中的条件顺序对程序很重要?这对我来说很奇怪,因为我从未见过或听说过在&amp;&amp; 的声明中的顺序很重要,因为我认为这两个 while 循环行是等效的。我一直在想这个问题,找不到答案。

谁能解释为什么会这样?

【问题讨论】:

  • 如果第一个表达式的计算结果为 false&amp;&amp; 将不会计算第二个表达式。阅读first line of the definition
  • 条件从左到右进行评估。 java使用短路逻辑。对于 AND 操作,如果左侧条件为假,则不会评估右侧条件。
  • 这个编译就好了。我愿意让它没有正确运行
  • 至于“为什么”,性能是一个原因(如果您已经知道结果将是什么,则无需继续评估。)但是您的确切情况是另一个原因。如果它总是同时评估两者,那么您将无法进行安全检查以确保 j&gt;=0 与检查 array[j] 的位置在同一行,因为它总是会尝试检查 array[j],即使它越界。但是通过短路,它不必尝试进行您知道会失败的检查。

标签: java while-loop conditional-statements


【解决方案1】:

如果您使用条件while (temp.compareTo(array[j]) &lt; 0 &amp;&amp; j &gt;= 0),则完全错误 在 Java 中,它首先检查条件&amp;&amp;,然后再检查||。 在条件&amp;&amp; 中,它会检查顺序。 因此,在您的情况下while (temp.compareTo(array[j]) &lt; 0 &amp;&amp; j &gt;= 0),它首先检查此条件temp.compareTo(array[j])。如果j 超出数组索引,==> 会出错

当你将条件改为while (j &gt;= 0 &amp;&amp; temp.compareTo(array[j]) &lt; 0)时,它首先检查j&gt;=0,如果j = -1程序不能继续下去。

【讨论】:

    【解决方案2】:

    让我们考虑以下示例:

    boolean b = Condition_1 && Condition_2;
    

    现在,如果 Condition_1 始终为假,那么无论 Condition_2 的值如何,b 都将始终为假。因此,当第一个条件为“和”时,无需检查第二个条件的值,这正是这里发生的情况。

    【讨论】:

      【解决方案3】:

      条件从左到右进行评估。

      最初,对于案例 j=-1,您的代码没有评估第二个条件,因为第一个条件抛出了 ArrayIndexOutOfBoundsException 异常。

      while (temp.compareTo(array[j]) < 0 && j >= 0)
      

      但是当你像这样切换条件时:

      while (j >= 0 && temp.compareTo(array[j]) < 0)
      

      那么对于同样的情况(j=-1),由于第一个条件变为false,那么不管第二个值如何,整个条件总是为假;因此不会评估第二个条件,因此在这种情况下也不例外。

      【讨论】:

        猜你喜欢
        • 2010-11-09
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 2011-11-02
        • 2015-12-16
        • 1970-01-01
        • 2023-03-06
        相关资源
        最近更新 更多