How does short-circuiting of && and || work in java? - java

Suppose we use and operator such that
if (a.enable() && b.enable())
so the above statements indicates that both the statements need to be true to proceed
What about the case if a.enable() return false, and if we write the statement such that
if (a.enable() && (b.enable() || c.enable()))
so this above statement means that a.enable() needs to be true and from the second part either b.enable() or c.enable() needs to be true. Either one of them needs to be true to proceed, but if a.enable() is not true then the condition fails without any further checks.
Is this correct?

Yes, && means AND, and || means OR. And they're both short-circuit, so in the following case:
if (a.enable() && b.enable())
b.enable() would not even be called if a.enable() returns false.
And in the following case:
if (a.enable() || b.enable())
b.enable() would not even be called af a.enable() returns true.
That's what allows conditions like
if (s != null && s.equals(foo))
which would cause a NullPointerException if the operator wasn't short-circuit.

if (a.enable() && b.enable())
The 2nd condition will be called only if the 1st condition is true.

Related

java new file not returning a boolean when part of a conditional

In my Java program, this creates a directory and returns a boolean true when successful:
new File(String.valueOf(subdir)).mkdir();
So why does that not work as the second part of this boolean? I.e., the directory does not get created and it does nt return a boolean true.
if (!subdir.exists() || new File(String.valueOf(subdir)).mkdir()) {
logger.error("subdir not created");
}
The second condition won't be calculated if the first condition is already true and the conditions are joined with OR || operator.
Similarly, second condition is not calculated for AND && operator if the first condition is false.
It is so called short circuit for logical operations - because it does not make sense to continue evaluation of other terms if the result of the expression is already defined:
false && any_operand == false
true || any_operand == true
So, in your case you need to use && in the condition and possibly use File::mkdirs() method to create parent directories if they don't exist:
if (!maint.exists() && !maint.mkdirs()) {
logger.info("no directories {} created", maint);
}

Java Evaluate IF statement

String groupType="local";
if(groupType==null ||groupType.equals("")||!groupType.equalsIgnoreCase("local")||!groupType.equalsIgnoreCase("global")||!groupType.equalsIgnoreCase("universal")){
System.out.print("evlauate to true ");
}
Why does this code evaluate to true, !groupType.equalsIgnoreCase("local") should set it to false ,
Even if you reduce the condition to
if (!groupType.equalsIgnoreCase("local")||!groupType.equalsIgnoreCase("global"))
It will always be true, since groupType can't be equal to both "local" and "global" at the same time.
You probably want to use && (AND) instead of || (OR).
if (groupType == null || groupType.equals("") ||
(!groupType.equalsIgnoreCase("local") && !groupType.equalsIgnoreCase("global") && !groupType.equalsIgnoreCase("universal"))) {
System.out.print("evaluate to true ");
}
Now it will evaluate to true if groupType is either null or empty or isn't equal to one of the values "local"/"global"/"universal". I'm assuming that's what you wanted.
Let's look at each of the operands of the || operator:
the string is equal to null? False.
the string is empty? False.
the string is not equal to "local"? False.
the string is not equal to "global"? True.
the string is not equal to "universal"? True.
Two of the conditions evaluate to true. Therefore, the whole if statement evaluates to true.
maybe you wanted this:
if(groupType==null ||groupType.equals("")
||!(groupType.equalsIgnoreCase("local")
||groupType.equalsIgnoreCase("global")
||groupType.equalsIgnoreCase("universal")
)
)

Java If block with multiple statements

I have a question about IF clause in Java.
I have and expression:
if ((someObject != null & connectedToTheInternet) || operate) {
// some action
}
Is my logic right: if someObject != null equals to true and connectedToTheInternet equals false then we have (someObject != null & connectedToTheInternet) equals false and then we have the following block:
if (false || operate) {
// some action
}
And if operate equals true then // some action will be triggered?
Just a first note: logical AND operator is "&&" and not just "&" (bitwise AND).
Following, your answer is YES... JVM will run conditions following your thinking.
By the way, I suggest you to read something abot short-circuit of these operators: it can be interesting if you are learning.
For example if you have if (a && (b || c) and a==false, then JVM won't evaluate b or c conditions because false && ... will be always false.
The same in the case of if (a || b || c && d): if a==true then JVM will ignore the other parts and consider it as true because true || .... will be always true.
Yes. if-clauses are evaluated from left to right. If no parenthesis are used, && has precedence, even higher precedence has ! (not) - similar to multiplication (AND), addition (OR) and negative numbers (-) in math (e.g. "A && (B || C) != A && B || C == (A && B) ||C") - I recommend to use parenthesis if you are unsure. This makes it possible to combine != null checks and calls to methods in the same if statement (e.g., if (object!=null && object.dosomething())).
Btw. there is a difference between & and && (short-circuit), when & is used, the second condition gets evaluated even if the first is false already. When && is used, Java doesn't check the second condition if the first one is false as the whole term cannot be true anymore - this is only important when the second condition is not a boolean variable but a method (which gets called or not -> side effects; this "skipping" is called short-circuit). Same for || and | where the second operator might not get evaluated if the first is already true (in case of ||).
Normally only ||and && are used.
Just for completeness: & is also the bitwise AND operator in Java.
if (false || operate) {
// some action
}
If operate true then if block executing.

How to use 'or' in Java?

I'm quite new to Java, and can't figure out how to use 'or'. What is the Java equivalent?
I've already tried && and || but eclipse does not recognise it.
This is part of my code:
if (action.equals ("run") || ("sprint")) {
System.out.println("you ran");
}
else {
System.out.println("else");
}
I've already tried && and || but eclipse does not recognise it.
That's very strange, but just to cover the basics: Let's assume you have the variable a and it contains the value 5. Then:
if (a == 5 || a == 7)
...will be true, because the first part of the expression (a == 5) is true. So the statement "a equals 5 or a equals 7" is true.
The || operator can only be used, in Java, where a boolean (true or false) expression is expected, such as in an if statement like the above. So pretty much in an if or a conditional operator (that ?...: thing, sometimes called the ternary operator).
Re your edit, the problem is that both sides of your || operator aren't true or false ("boolean") expressions. Your statement:
if (action.equals ("run") || ("sprint")){
breaks down like this:
if (
action.equals ("run")
|| // ("or")
("sprint")
)
the second part of that isn't a true/false, it's a string. The correct way to express that in Java (or nearly any other programming language) is:
if (action.equals ("run") || action.equals ("sprint")){
Now both sides of the || result in true/false exprssions:
if (
action.equals ("run")
|| // ("or")
action.equals ("sprint")
)
The reason for this is that the second part may have nothing whatsoever to do with action, and so the compiler can't assume you mean to re-use it in the second part of the expression. You might, for instance, want to use || with two completely unrelated things:
if (action.equals("run") || somethingElse.equals("run")) {
Ok. ("sprint") is not a Boolean expression. Since a if condition expects a Boolean expression your code returns an error. You should change the line with:
if (action.equals ("run") || action.equals("sprint")){
The equals method returns a boolean and the || operator wants two booleans on each side.
You're doing an action.equals("run") on one side but then a ("sprint") on the other which isn't a boolean expression.
Change your code like so:
if (action.equals("run") || action.equals("sprint")){

How does Java deal with multiple conditions inside a single IF statement

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

Categories