shanwu
shanwu

Reputation: 1705

how does Java handle && inside if statement

I don't understand the reason why the follow java code throws a ArrayIndexOutofBound exception

    while (intArray[j] < intArray[j - 1] && j > 0) {
        int temp = intArray[j - 1];
        intArray[j - 1] = intArray[j];
        intArray[j] = temp; 
        j--;
    }

It appears that even if I AND(&&) both conditions, it will execute one of the conditions first to check if it qualifies the condition, in this case, it will be intArray[0] < intArray[-1] and cause out of bound exception. Which confuses me at first, now I just wandering, why does the program behave that way?

Upvotes: 0

Views: 93

Answers (4)

Luis Sieira
Luis Sieira

Reputation: 31612

Java uses lazy evaluation from left to right. You may be getting this exception for three reasons.

  • If j<0 then intArray[j] will throw an exception
  • If j<1 then intArray[j-1] will throw an exception
  • If j>=intArray.length, then intArray[j] will throw an exception.

Also, your loop should consider j < intArray.length

Anyway, if you're trying to implement a sinking/bubble algorithm, your code is wrong, it will stop as soon as it finds a sorted couple of elements. And repeat itself ad nauseam.

Upvotes: 1

mmalik
mmalik

Reputation: 185

Should be like this:

while (j > 0 && intArray[j] < intArray[j - 1]) {
        int temp = intArray[j - 1];
        intArray[j - 1] = intArray[j];
        intArray[j] = temp; 
        j--;
    }

If the first condition, j > 0 is false, then the second one isn't evaluated (and does't throw any exception of course).

If you used single & instead of &&, the order of conditions wouldn't matter, because both would be evaluated, even if the first one was false.

Edit

A simple example of the difference between & (bitwise AND operation) and && (Conditional-AND)

public class LogicalOperators {

    public static void main(String[] args) {

        int n = 0;
        int k = 5;

        if(n != 0 && k % n == 0) {
            System.out.println(n + " is a divisor of " + k);
        }

        if(n != 0 & k % n == 0) {
            System.out.println(n + " is a divisor of " + k); // throws ArithmeticException
        }
    }
}

Upvotes: 1

Nishant Chawla
Nishant Chawla

Reputation: 11

This will fail when the value of j will become 1. It will enter into the loop after executing to the last step it will become 0. When again it reaches the next step it will compare int[0] to int[-1] which will eventually throw arrayindexout of bound because it will get evaluated befor j>0.

Upvotes: 0

Eran
Eran

Reputation: 394146

The condition is evaluated from left to right, which means intArray[j] < intArray[j - 1] is evaluated first. Therefore if j<=0, you'll get an exception.

Changing the order to

while (j > 0 && intArray[j] < intArray[j - 1]) {

will prevent the exception (assuming the initial value of j is not too high).

Upvotes: 4

Related Questions