&& (AND) and || (OR) in IF statements - java

I have the following code:
if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){
partialHits.get(z).put(z, tmpmap.get(z));
}
where partialHits is a HashMap. What will happen if the first statement is true? Will Java still check the second statement? Because in order the first statement to be true, the HashMap should not contain the given key, so if the second statement is checked, I will get NullPointerException.
So in simple words, if we have the following code
if(a && b)
if(a || b)
would Java check b if a is false in the first case and if a is true in the second case?

No, it will not be evaluated. And this is very useful. For example, if you need to test whether a String is not null or empty, you can write:
if (str != null && !str.isEmpty()) {
doSomethingWith(str.charAt(0));
}
or, the other way around
if (str == null || str.isEmpty()) {
complainAboutUnusableString();
} else {
doSomethingWith(str.charAt(0));
}
If we didn't have 'short-circuits' in Java, we'd receive a lot of NullPointerExceptions in the above lines of code.

Java has 5 different boolean compare operators: &, &&, |, ||, ^
& and && are "and" operators, | and || "or" operators, ^ is "xor"
The single ones will check every parameter, regardless of the values, before checking the values of the parameters.
The double ones will first check the left parameter and its value and if true (||) or false (&&) leave the second one untouched.
Sound compilcated? An easy example should make it clear:
Given for all examples:
String aString = null;
AND:
if (aString != null & aString.equals("lala"))
Both parameters are checked before the evaluation is done and a NullPointerException will be thrown for the second parameter.
if (aString != null && aString.equals("lala"))
The first parameter is checked and it returns false, so the second paramter won't be checked, because the result is false anyway.
The same for OR:
if (aString == null | !aString.equals("lala"))
Will raise NullPointerException, too.
if (aString == null || !aString.equals("lala"))
The first parameter is checked and it returns true, so the second paramter won't be checked, because the result is true anyway.
XOR can't be optimized, because it depends on both parameters.

No it will not be checked. This behaviour is called short-circuit evaluation and is a feature in many languages including Java.

All the answers here are great but, just to illustrate where this comes from, for questions like this it's good to go to the source: the Java Language Specification.
Section 15:23, Conditional-And operator (&&), says:
The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. [...] At run time, the left-hand operand expression is evaluated first [...] if the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated [...] the resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.
And similarly, Section 15:24, Conditional-Or operator (||), says:
The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. [...] At run time, the left-hand operand expression is evaluated first; [...] if the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; [...] the resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.
A little repetitive, maybe, but the best confirmation of exactly how they work. Similarly the conditional operator (?:) only evaluates the appropriate 'half' (left half if the value is true, right half if it's false), allowing the use of expressions like:
int x = (y == null) ? 0 : y.getFoo();
without a NullPointerException.

Short circuit here means that the second condition won't be evaluated.
If ( A && B ) will result in short circuit if A is False.
If ( A && B ) will not result in short Circuit if A is True.
If ( A || B ) will result in short circuit if A is True.
If ( A || B ) will not result in short circuit if A is False.

No, if a is true (in a or test), b will not be tested, as the result of the test will always be true, whatever is the value of the b expression.
Make a simple test:
if (true || ((String) null).equals("foobar")) {
...
}
will not throw a NullPointerException!

No it won't, Java will short-circuit and stop evaluating once it knows the result.

Yes, the short-circuit evaluation for boolean expressions is the default behaviour in all the C-like family.
An interesting fact is that Java also uses the & and | as logic operands (they are overloaded, with int types they are the expected bitwise operations) to evaluate all the terms in the expression, which is also useful when you need the side-effects.

This goes back to the basic difference between & and &&, | and ||
BTW you perform the same tasks many times. Not sure if efficiency is an issue. You could remove some of the duplication.
Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){
partialHits.get(z).put(z, z3);
}

Related

Short circuiting logical operators, precedence, and evaluation order? [duplicate]

In JavaScript and Java, the equals operator (== or ===) has a higher precedence than the OR operator (||). Yet both languages (JS, Java) support short-circuiting in if statements:
When we have if(true || anything()), anything() isn't evaluated.
You can also have the following expression: true || foo == getValue()) - for example in an output statement such as console.log(...);, or in an assignment.
Now, according to operator precedence, short-circuiting shouldn't happen, as === = == > || in terms of precedence. (In other words, the comparison should happen first, for which getValue() ought to be called, as the equality check has a higher precedence that the OR comparison.) But it does. getValue() isn't called (as can easily be checked by putting an output statement into its body).
Why (does short circuiting work when the operator precedence says it shouldn't)?
Or am I confusing matters?
Or am I confusing matters?
You are. I think it's much simpler to think about precedence as grouping than ordering. It affects the order of evaluation, but only because it changes the grouping.
I don't know about Javascript for sure, but in Java operands are always evaluated in left-to-right order. The fact that == has higher precedence than || just means that
true || foo == getValue()
is evaluated as
true || (foo == getValue())
rather than
(true || foo) == getValue()
If you just think about precedence in that way, and then consider that evaluation is always left-to-right (so the left operand of || is always evaluated before the right operand, for example) then everything's simple - and getValue() is never evaluated due to short-circuiting.
To remove short-circuiting from the equation, consider this example instead:
A + B * C
... where A, B and C could just be variables, or they could be other expressions such as method calls. In Java, this is guaranteed to be evaluated as:
Evaluate A (and remember it for later)
Evaluate B
Evaluate C
Multiply the results of evaluating B and C
Add the result of evaluating A with the result of the multiplication
Note how even though * has higher precedence than +, A is still evaluated before either B or C. If you want to think of precedence in terms of ordering, note how the multiplication still happens before the addition - but it still fulfills the left-to-right evaluation order too.
According to the language specification, https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24
At run time, the left-hand operand expression is evaluated first; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8).
If the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated.
So if you have a || b==c, it is not interpreted as (a || b) == c, because || has lower precedence, as you found in the tutorial. Instead, it is interpreted as a || (b==c). Now since a is the left side of ||, it is evaluated first.
There is no operator precedence in this case. What you are questioning is like in f(callback) statement the callback function being evaluated even before f. This can not happen.
On the other hand, in JS the || is one of the few places where you can watch laziness at show. The == operand (think as if it is an infix function like in fully functional languages) takes two arguments and the one on the left gets evaluated first. If it resolves to true the second argument doesn't even get evaluated.

Evaluation order of Java operators && vs ||

I have this simple code block
int a = 10;
int b = 20;
int c = 30;
boolean result = a++ == 10 || b++ == 20 && c++ < 30;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(result);
When I run this, the console is
11
20
30
true
This result tell me that only a++ == 10 is evaluated.
As I read from this https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html,
operator && have higher priority than || and should be evaluated first. In this book OCA Java SE 8 Programmer I Certification Guide, at twist 2.4, a similar example give the answer that all the logical operands will be evaluated. && is evaluated first and || is the last.
But the result give me an assumption that the priority is just used to group operands and operators.
From this a++ == 10 || b++ == 20 && c++ < 30 to this a++ == 10 || (b++ == 20 && c++ < 30) When expression is evaluated, it is short-circuited by the value true on the left of ||. So the expression on the right (the && operator) is not evaluated.
Because if the operator && is evaluated first, the value of b and c will be increased but it does not.
Am I correct? Please help.
The evaluation order without parenthesis is from left to right.
Since the first evaluation was true and because the operant is || the rest is not executing. (The same will happened if your first result was false and then you have an && operant).
The ++ operator executes always after the comparison execution.
(In C++ there are two different operators ++c and c++ then you can choose when the addition takes place)
Nice thoughts!!!
The tutorial page on operators only gives you an informal description of the operator precedence, when the java code is executed. The table shown on the page does not exists as such in the JLS. The execution/evaluation order depends on how the source code is parsed and how the parse tree is generated.
A code fragment as a || b && c (in this example code) will be parsed as an Expression:
Expression:
LambdaExpression
AssignmentExpression
In this case, it's an AssignmentExpression:
AssignmentExpression:
ConditionalExpression
Assignment
In this case, it's a ConditionalExpression:
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression
ConditionalOrExpression ? Expression : LambdaExpression
In this case, it's a ConditionalOrExpression (the first line, not the one with the tenary operator):
ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression || ConditionalAndExpression
And here we will have it translated to the second line (ConditionalOrExpression || ConditionalAndExpression) as we have the "||" characters here (the actual || operator).
The JLS specifies that the left operand of the || operator is evaluated first by 15.7.1. Evaluate Left-Hand Operand First:
The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
It also specifies, that the || operator is "short-circuited", as defined in 15.24. Conditional-Or Operator ||:
The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.
In total this means that the left operand is evaluated (a++ == 10, which will increase the variable a) and because this comparison results in true, the right operand will NOT be evaluated. So neither b++ nor c++ will be evaluated in any way.
This result tell me that only a++ == 10 is evaluated.
Which is the result that the language definition dictates.
But the result give me an assumption that the priority is just used to
group operands and operators.
You are correct.

Working of short circuit and unary operator

Please have a look at the following code:
int i=5;
boolean b = i<5 && ++i<5;//line 2
System.out.println(i);//line 3, prints 5
In line 2, according to my understanding: Since among all the operators, ++ has highest precedence ++i should be evaluated first. But line 3 actually is printing i=5 (and not 6). Meaning, && has evaluated before ++ operator. How is it possible?
EDIT: From the answers I see that "In Java, all expressions are evaluated from left to right.". But when does actually precedence order comes into play. In following code:
int a=1,b=1,c=1;
boolean b = a==b&&b==c;//Line2
In line2 code would't just run from left to right. First a==b is evaluated then b==c and then && operator. Can you please explain more?
That's not how the expression is processed.
In Java, all expressions are evaluated from left to right. Operator precedence only comes into play when considering the evaluation of the arguments of &&.
So i < 5 is computed before ++i < 5 is even considered.
In this case ++i < 5 will not be evaluated, since i < 5 is false. So i stays at 5.
The key is: ++ has the highest precedence inside a expression, but the sentence boolean b = i<5 && ++i<5 has two expressions evaluated from left to right.
Think of b = i<5 && ++i<5 like:
if( i<5 ){
if ( ++i<5 ){
return true;
}
}
Considering your edited answer, the second code snippet also evaluates from left to right.
In both cases there is an expression of the form A && B with A as the left argument and B as the right argument of &&.
Here is where "left-to-right" applies. First, the left expression A is evaluated. In your first code snippet, that is i<5 and since this expression evaluates to false, the second argument to that isn't even considered, since the whole expression will evaluate to false (short-circuiting).
In your second snippet you have as left argument a==b. Since that evaluates to true, only now the second argument is considered, which also evaluates to true. That leaves you with true && true which can then be processed further.
Your misunderstanding is in how the '&&' works. When you use them java uses short circuit or lazy evaluation.
boolean equal = 1==1 && 1==2 java evaluates the 1==1 sees it as true, checks the ampersands and has to evaluate the 1==2 which is false and therefore equal is false.
boolean equal = 1==2 && 1==1 java evaluates the 1==2 sees it as false, then checks the ampersands and can see that whether the next expression is true or false the outcome is the same, that equal is false. Therefor it never evaluates the second equation.
More plainly the second example is saying boolean equal = false & true. This can only be true if both are true. Thus knowing the first is false is all we need to know the outcome. By ignoring the sencond expression at this point we can save needless calculations.

How can I evaluate the bitwise operator in this condition?

I just practice some basic Java practice problems and this below shows up.
if((b2 = false) | (21 % 5)>2) return true;
So b2 is assigned with false and 1 > 2 is certainly false, but how do we evaluate "|" ? should it return true?
b2 = false assigns false to the variable b2, and the expression has the value false. | on booleans means "or" (without short-circuit), so it evaluates both operands, and the outcome is true if either operand is true.
It is not a bitwise operator. If you use | on integers, it is a bitwise operator. If you use | on booleans, it is a logical operator.
Edit:
|| is a short-circuit operator. If you write (a() || b()), and a() evaluates to true, then b() will not be evaluated, because the result of the or must be true. Single | does not short-circuit, so both operands are always evaluated.
(b2 = false)
(Edited after khelwood's correction) This is also an assignment, not just a logical operation, so be careful for side effects.
And yes, for a boolean, "|" is "or" (and not bitwise), so if the first operator is true, it will always be true.

Why does the "or" go before the "and"?

int it=9, at=9;
if(it>4 || ++at>10 && it>0)
{
System.out.print("stuff");
}
System.out.print(at);
prints out stuff9 and I want to know why as I thought ++at>10 && it>0 would be evaluated first and thus make at = 10.
Operator precedence only controls argument grouping; it has no effect on execution order. In almost all cases, the rules of Java say that statements are executed from left to right. The precedence of || and && causes the if control expression to be evaluated as
it>4 || (++at>10 && it>0)
but the higher precedence of && does not mean that the && gets evaluated first. Instead,
it>4
is evaluated, and since it's true, the short-circuit behavior of || means the right-hand side isn't evaluated at all.
Your compound expression is equivalent to
if(it>4 || (++at>10 && it>0))
due to Java operator precedence rules. The operands of || are evaluated left to right, so it>4 is evaluated first, which is true, so the rest of it (the entire && subexpression) doesn't need to be evaluated at all (and so at does not change).
I feel I should add how to actually get your expected output.
Brief explanation: the || operator short-circuits the entire expression, thus the right side not even being evaluated.
But, to not short-circuit and get your expected output, instead of the || operator, just use |, like so:
int a = 9, b = 9;
if(a>4 | ++b>10 && a>0)
{
System.out.print("stuff");
}
System.out.print(b);
The output to that is stuff10
This way, regardless of one side being true or not, they're both still evaluated.
The same thing goes for && and &

Categories

Resources