Lets say I have this:
if(bool1 && bool2 && bool3) {
...
}
Now. Is Java smart enough to skip checking bool2 and bool3 if bool1 was evaluated to false? Does java even check them from left to right?
I'm asking this because i was "sorting" the conditions inside my if statements by the time it takes to do them (starting with the cheapest ones on the left). Now I'm not sure if this gives me any performance benefits because i don't know how Java handles this.
Yes, Java (similar to other mainstream languages) uses lazy evaluation short-circuiting which means it evaluates as little as possible.
This means that the following code is completely safe:
if(p != null && p.getAge() > 10)
Also, a || b never evaluates b if a evaluates to true.
Is Java smart enough to skip checking bool2 and bool2 if bool1 was evaluated to false?
Its not a matter of being smart, its a requirement specified in the language. Otherwise you couldn't write expressions like.
if(s != null && s.length() > 0)
or
if(s == null || s.length() == 0)
BTW if you use & and | it will always evaluate both sides of the expression.
Please look up the difference between & and && in Java (the same applies to | and ||).
& and | are just logical operators, while && and || are conditional logical operators, which in your example means that
if(bool1 && bool2 && bool3) {
will skip bool2 and bool3 if bool1 is false, and
if(bool1 & bool2 & bool3) {
will evaluate all conditions regardless of their values.
For example, given:
boolean foo() {
System.out.println("foo");
return true;
}
if(foo() | foo()) will print foo twice, and if(foo() || foo()) - just once.
Yes,that is called short-circuiting.
Please take a look at this wikipedia page on short-circuiting
Related
This question already has answers here:
Does Java evaluate remaining conditions after boolean result is known?
(7 answers)
Closed 7 years ago.
Does java calculate the second condition in ( test1 || test2 ) if the first one is true ?
I use Optional and I have something like that :
if (!opt.isPresent() || opt.get() == currentPlayer.getSelectedRegion())
and there will be a problem if the first test is true and java compute the second test.
If first condition is true second condition is not evaluated.
If first condition is false also second condition is evaluated.
That's why you can write a code like the following without a NullPointerException
if (str == null || str.length() == 0) {
// do something
}
The operator | (instead of || ) will evaluated both conditions
So the code
if (str == null | str.length() == 0) {
// do something
}
can generate a NullPointerException if str is null
Does java calculate the second condition in ( test1 || test2 ) if the first one is true ?
No. Boolean or will short-circuit, the first true is sufficient to make the expression true. No further conditions will be evaluated after that.
If you use the || and &&, rather than the | and &, Java will not bother to evaluate the right-hand operand.
No, java short-cut operators, the second argument is not evaluated if the first is. Ore more formal:
for x || y, y is only evaluated if x is false; and
for x && y, x is only evaluated if y is true.
This will increase performance and can be both useful and tricky:
usefull: to prevent you from doing things such that an error is thrown. The most typical example is the null check:
if(x != null && x.someTest())
this will prevent .someTest being called if x is null.
tricky: the problematic aspect can be if you call a method that does not only return something, but changes state as well. For instance:
public class Foo {
private int checked = 0;
bool someCondition () {
return (checked % 2) == 0;
}
bool neverChecked () {
checked++;
return checked == 1;
}
}
if you now call:
if(foo.someCondition() || foo.neverChecked());
this is one of the main reasons it is adviseable to keep "getters" (thinks that calculate things of an object), and "setters" (things that modify the state of an object), clearly separated. From the moment you start mixing, one can get complicated behavior in some circumstances.
it can be the intention that you always increment checked, but it will only if .someCondition happens to be false.
return super.isAvailable() && expander != null
&& rightNotLeft ? !expander.isExpandedRight() : expander.isExpandedRight();
My problem was that when expander was null I was getting a null pointer exception. But I didn't think that this should happen since expander!=null is being evaluated to false and since ANDs are being used the entire expression should short circuit and return false.
return super.isAvailable() && expander != null
&& (rightNotLeft ? !expander.isExpandedRight() : expander.isExpandedRight());
The above code (adding the parentheses) solved the problem. However this does not make sense to me as no matter what happens in the conditional operator there is no way to return true so shouldn't it short circuit?
Thank you for your responses.
This is due to operator precedence. Your condition without explicit parentheses is actually evaluated like
return (super.isAvailable() && expander != null
&& rightNotLeft) ? !expander.isExpandedRight() : expander.isExpandedRight();
This question already has answers here:
short-circuiting behavior of conditional OR operator(||)
(3 answers)
Two conditions in one if statement does the second matter if the first is false?
(7 answers)
Closed 8 years ago.
if i have a while condition in java as follows while(j>=1 && i<=7) my question is if the first condition fails then the second condition will be examine??
in other word if j=0 the compiler will check if I<=7 or it will ignore it .
please help me
thank you
No, if the first condition returns false then the whole expression automatically returns false.
Java will not bother examining the other condition.
(j>=1 && i<=7 && cond1 && cond2 && ... && condN) // will evaluate until the one condition fails
(j>=1 & i<=7 & cond1 & cond2 & ... & condN) // will evaluate all the conditions
and with or
(j>=1 || i<=7 || cond1 || cond2 || ... || condN) // will evaluate until the one condition is true
(j>=1 | i<=7 | cond1 | cond2 | ... | condN) // will evaluate all conditions
example:
lets use this 2 methods:
public boolean isTrue(){
System.out.println("true");
return true;
}
public boolean isFalse(){
System.out.println("false");
return false;
}
so, in the first case:
boolean cond = isFalse() && isTrue();
output is:
false
value of cond is false
and in the second case:
boolean cond = isFalse() & isTrue();
output is:
false
true
value of cond is false
It won't. Logical operator && shortcuts and will stop evaluation if its left side argument is false.
Note that Java also has logical (in addition to the bitwise &!) operator &, which will not shortcut; therefore, if a is a boolean expression evaluating to false in a & b, then b will be evaluated nonetheless (but the end result will still be false).
No while evaluating && if the first condition is false then it doesn't evaluate the second condition.
Similarly while evaluating || if the first condition is true then the second condition is not evaluated.
This is called lazy evaluation. In order to make it greedy, use the single ampersand logical operator. In that case, it will also evaluate the second conditional, even if the first turns out to be false.
I agree with what others are saying. The answer is no. This is known as short-circuit evaluation.
http://en.wikipedia.org/wiki/Short-circuit_evaluation
Ok, i am building program to check many fields. If at least 1 field is not ok then i don't want my program to spend time to check other fields. So let look at this code:
// Util.isReadyToUse method return true if the string is ready for using, & return false if it is not.
boolean isOK=true;
if(!Util.isReadyToUse(firstName)){
isOK=false;
}
else if(isOK && !Util.isReadyToUse(lastName)){
isOK=false;
}
else if(isOK && !Util.isReadyToUse(email)){
isOK=false;
}
.....more checking
if(isOK) {
//do sthing
}
Ok, when running, the program will first check !Util.isReadyToUse(firstName). Suppose it returns (isOK=false). Next the program will check isOK && !Util.isReadyToUse(lastName).
So my question here is that Since the isOK currently false, then will the program spend time to check the condition !Util.isReadyToUse(lastName) after &&?
Ok, As a human being, if you see isOK=false and now you see isOK && !Util.isReadyToUse(email), then you don't want to waste time to look at !Util.isReadyToUse(email) since isOK=false and u saw && after isOK.
Will machine also work like that?
I am thinking to use break but why people say break doesn't work in if statement:
if(!Util.isReadyToUse(firstName)){
isOK=false;
break;
}
else if(isOK && !Util.isReadyToUse(lastName)){
isOK=false;
break;
}......
What is the best solution in this situation?
So my question here is that Since the isOK currently false, then will
the program spend time to check the condition
!Util.isReadyToUse(lastName) after &&?
Java is smart, if you have a condition if(somethingFlase && something), then something won't be reached due to Short-circuit evaluation. Since the whole expression will be false regardless of the second condition, there is no need for Java to evaluate that.
From 15.23. Conditional-And Operator &&:
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.
if(a && b) - if a is false, b won't be checked.
if(a && b) - if a is true, b will be checked, because if it's false, the expression will be false.
if(a || b) - if a is true, b won't be checked, because this is true anyway.
if(a || b) - if a is false, b will be checked, because if b is true then it'll be true.
No, it shortcuts the rest of the predicate.
That's you'll see things like
if(A != null && A.SomeVal == someOtherVal)
Java supports what is referred to as Short-Circuit Evaluation. See this page:
http://en.wikipedia.org/wiki/Short-circuit_evaluation
What this means is that if the first boolean in your statement is enough to satisfy the statement, then the rest of the values are skipped. If we have the following:
boolean a = false;
boolean b = true;
if(a && b) /*Do something*/;
'b' will never be checked, because the false value for 'a' was enough to break out of the if statement.
That being said, your program will never take advantage of this because the only time isOK is set to false is within one of your else if statements.
As the other responders mentioned Java will do the smart thing.
But it could be the case that you want Java to continue to check, in that case you can use & vs && or | vs ||.
if (someMethod() | anotherMethod() {
If the first method reutrns true, Java will still execute the second method.
if (someMethod() & anotherMethod() {
If the first method is false, Java will still execute the second method.
No, Java won't "waste time" for it. It's called short circuit evaluation.
This mechanism is commonly used e.g. for null checking :
if (foo != null && foo.neverFailsWithNPE()) {
// ...
}
You don't need to use break on an if..else if.. else statement because once it finds a condition which is true the rest aren't even looked at.
Let's take a simple example of an object Cat. I want to be sure the "not null" cat is either orange or grey.
if(cat != null && cat.getColor() == "orange" || cat.getColor() == "grey") {
//do stuff
}
I believe AND comes first, then the OR. I'm kinda fuzzy though, so here are my questions:
Can someone walk me through this statement so I'm sure I get what happens?
Also, what happens if I add parentheses; does that change the order of operations?
Will my order of operations change from language to language?
The Java Tutorials has a list illustrating operator precedence. The equality operators will be evaluated first, then &&, then ||. Parentheses will be evaluated before anything else, so adding them can change the order. This is usually pretty much the same from language to language, but it's always a good idea to double check.
It's the small variations in behavior that you're not expecting that can cause you to spend an entire day debugging, so it's a good idea to put the parentheses in place so you're sure what the order of evaluation will be.
Boolean order of operations (in all languages I believe):
parens
NOT
AND
OR
So your logic above is equivalent to:
(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
The expression is basically identical to:
if ( (cat != null && cat.getColor() == "orange") || cat.getColor() == "grey") {
...
}
The order of precedence here is that AND (&&) has higher precedence than OR (||).
You should also know that using == to test for String equality will sometimes work in Java but it is not how you should do it. You should do:
if (cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
...
}
ie use the equals() methods for String comparison, not == which simply does reference equality. Reference equality for strings can be misleading. For example:
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false
First, your if statement contains three main expressions:
cat != null
cat.getColor() == "orange"
cat.getColor() == "grey"
The first expression simply checks whether cat is not null. Its necessary otherwise the the second expression will get executed and will result in a NPE(null pointer excpetion). That's why the use of && between the first and second expression. When you use &&, if the first expression evaluates to false the second expression is never executed.
Finally you check whether the cat's color is grey.
Finally note that your if statement is
still wrong because if cat is
null, the third expression is still
executed and hence you get a null
pointer exception.
The right way of doing it is:
if(cat != null && (cat.getColor() == "orange" || cat.getColor() == "grey")) {
//do stuff
}
Check the order of parenthesis.
Yeah && is definitely evaluated before ||. But I see you are doing cat.getColor() == "orange" which might give you unexpected result. You may want to this instead :
if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
//do stuff
}
Order of Operation is not what you need, you need boolean algebra, this includes boolean functions. Maxterms/minterms, Gray code, Karnaugh tables, diodes,transistors, logic gates, multiplexers, bitadders, flip flops...
What you want is to implement boolean "logic" on computers or virtual machines. With "order of operations" you may refer something about physics like managing delays on logic gates (OR, if) nanoseconds intervals?