Are there logically any difference between
if (name.startsWith("a"){
return true;
} else if (name.startsWith("b") {
return true;
} else if (name.startsWith("c") {
return true;
}
and
if(name.startsWith("a") || name.startsWith("b") || name.startsWith("c") ){
return true;
}
I prefer the second one as it is elegant to me. I'd like to understand "are there any differences?"
They're the same.
The second one is definitely easier to read, and readability is incredibly important in programming.
The rule I like to go by is that if multiple branches of an if-else statement produce the same behavior, I combine them. (Be sure that they're the EXACT same behavior)
In this case: no.
Boolean expressions with || and && use short-circuiting, which means that B is ignored in A || B if A already evaluated to true. Therefore, the first alternative is not more efficient.
If the body of the if clause gets bigger though, and contains the same code, then you absolutely don't want to use the first version:
if (name.startsWith("a"){
// lots of code
} else if (name.startsWith("b") {
// lost of the same code
}
Code duplication is a terrible sin and often the cause for annoying bugs.
They're equivalent, but the second one is preferable as it's more concise - you'd use the first one if the different conditions should be handled differently, e.g.
if(name.startsWith("a")) {
System.out.println("first side effect");
return true;
} else if (name.startsWith("b")) {
System.out.println("a different side effect");
return true;
}
Both will do the stuff.
And The last and the best one. i.e LOGICAL OR
if(name.startsWith("a") || name.startsWith("b"){
etc...
}
Because in logical ||
In this case It's just short-circuiting.
in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression:
They are logically identical. The second one is certainly more elegant and concise though.
Of course, neither snippet of code will work because you have forgotten closing braces. :)
No difference in this case. They're equivalent.
Related
The a couple weeks ago I submit a function for code review that looked like this.
Function{
If (condition)
Else If (condition)
Else if (condition)
Else
return value
}
My lead giving the code review said "I hate else if," but he didn't say why or what I should have done instead. He just gave me the go ahead to upload this function.
My question is what are some alternatives to a bunch of "else ifs" that would make the code look more elegant and maybe perform better?
I tried pulling up his code to get an idea of what he would have done and I noticed several times he did
If (condition)
If (condition)
If (condition)
Should I avoid writing "else"? I was going to ask him but he no longer works here.
Thank you
I try to avoid "else", "else if" and also "if" and "for". In my point of view, branching and looping add complexity to code. But it's everytime depends on what you want to do. Some examples:
If you do thing like:
if fruit.isBanana() then fruit.eatBanana()
else if fruit.isOrange() then fruit.eatOrange()
...
Instead of this, you can use inheritance:
class Banana extends Fruit {
function eat() {
... yum yum yum banana ...
}
}
class Orange extends Fruit {
function eat() {
... yum yum yum orange ...
}
}
And then, if you have an instance:
fruit.eat()
Another example: If you use "if" and "for" for filtering:
longFruits = []
for fruit in fruits {
if fruit.isBanana() then longFruits.add(fruit)
}
then you can work with collections instead:
longFruits = CollectionUtils.select(fruits, Precicate.isBanana)
This is just a couple examples and technics.
You can use switches.
switch (variable) {
case 1:
doSomething();
break;
case 2:
doSomething();
break;
case 3:
doSomething();
break;
default:
doSomething();
break;
}
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Oops, I misread your question, so you probably already know this, but anyway:
This is how it works:
Example 1
if your program looks like this:
if(condition1){ doThing1(); }
else if(condition2){ doThing2(); }
else if(condition3){ doThing3(); }
else{ doThing4() }
done();
Your program is first going to check if condition1 is true. if it is, it's going to run the method doThing1(). Afterwards it will not check condition2 or condition3, and will go directly to the done()-method.
If condition1 is false, the program will check if condition2 is true. If it is, it will run the method doThing2() and afterwards it will go directly to the done()-method.
If condition1 and condition2 is false, the program will check if condition3 is true and if it is, run the doThing3()-method.
If none of the conditions are true, it will run the method doThing4() and afterwards the done-method.
Example 2:
However, if your program looks like this:
if(condition1){ doThing1(); }
if(condition2){ doThing2(); }
if(condition3){ doThing3(); }
done();
Your program first checks if condition1 is true, if it is, it runs the method doThing1()
Then it checks if condition2 is true, if it is, it runs the doThing2()-method
Then it checks if condition3 is true, if it is, it runs the doThing3()-method
Lastly, it runs the done()-method.
The difference is that in example 1, the program doesn't check condition2 or condition3 if condition1 is true, whereas in example 2, it always checks all of the conditions. This means that in example 1, only one of the methods doThing1(), doThing2(), doThing3() and doThing4() is going to be run. In example 2 however, if more than one of the conditions are true, the program will run more than one of the methods.
Try writing a simple program where you use the two examples and change doThing1(); to System.out.println("1"); and so on, and try out different combinations of values (true or false) for the conditions if you didn't understand my answer.
I would use spacing to make sure the code looks neat without changing the actual meaning of the code. you can use switch, as explained in shinjw:s answer, but that isn't always practical since you have to use a byte, short, char or int to determine the outcome. Just write
if(condition1) //place1
else if(condition2) //place2
else if(condition3) //place3
else //place4
to make sure the conditions are nicely lined up if you want that, but only use that if the thing you are going to write at place 1,2,3 and 4 is one line. Otherwise it looks weird. If lining up the conditions isn't that important, I would write
if(condition1) //code1
else if(condition2) //code2
else if(condition3) //code3
else //code4
Since Java isn't space sensitive, any place you could use one space you could use any number of spaces and anytime you could use one new line, you could use any number of blank lines. It's not the tabbing, but the {} that divides code.
Right up front: I like else if. I think it makes for good clean code, unless one can design away the need for a series of comparisons. That said, ...
else if is not a first-class construct in Java. It's actually an if nested inside an else. From the JLS 7 (since OP indicates they use Java 6 and I don't have the JLS for that), an IfThenElseStatement is
if ( Expression ) StatementNoShortIf else Statement
where Expression is any Java Expression that evaluates to a boolean or Boolean, and StatementNoShortIf is any Java Statement that does not end in an if with no else.
We get an else if by substituting another if statement for Statement (following the else). So
// example 1
if (condition0) {
// body 0
} else if (condition1) {
// body 1
} else if (condition2) {
// body 2
} else {
// body 3
}
is, as far as Java is concerned, identical to:
// example 2
if (condition0) {
// body 0
} else {
if (condition1) {
// body 1
} else {
if (condition2) {
// body 2
} else {
// body 3
}
}
}
The only difference syntactically is that in example 2 no braces have been omitted (or, put another way, nested if statements have been enclosed in a Block). The else if construct is possible solely because those enclosing Blocks are unnecessary.
It is possible that your former lead prefers to use braces wherever they can be used, thinking that this is somehow safer or more readable. I disagree with this idea: as I said, else if makes for cleaner code IMO. But the only time a series of disconnected if statements better in any sense than if else is when the conditions and associated actions are truly independent of each other.
I have the following lines in my code:
if (command.equals("sort") && args.length == 2) {
//run some program
}
Someone suggests that I should use two separate if statements because there's no need to evaluate any of the other if statements if the command does not equal to "sort", regardless of whether or not the args length is correct.
So according to that that, I need to rewrite my code to:
if (command.equals("sort")) {
if (args.length == 2) {
//run some program
}
}
I know they both do the job, but my question is which one is better and more efficient?
No, that's not true. They call it short circuit, if the first condition evaluates as false, the second one would not be evaluated at all.
Well, since && is a short-circuit operator. So both the if statements are effectively the same.
So, in first case, if your command.equals("sort"), returns false, the following condition will not be evaluated at all. So, in my opinion, just go with the first one. It's clearer.
As stated, short circuit will cause the program to exit the if statement the moment a condition fails, meaning any further conditions will not be evaluated, so there's no real difference in the way the two formats are evaluated.
I would like to note that code legibility is negatively affected when you have several if statements nested within each other, and that to me is the main reason not to nest. For example:
if( conditionA && conditionaB && !conditionC ){
// Do Something
}
is much cleaner than:
if( conditionA ){
if( conditionB ){
if( !conditionC ){
// Do Something
}
}
}
Imagine that with 20 nested if statements? Not a common occurrence, sure, but possible.
They are the same. For your first example, any modern runtime will ignore the second expression if the first expression is false.
short circuiting is better which is done by && if you are check null case for a value and then apply a function on that object, short circuit operator works well. It stops from condition 2 to be executed if condition 1 is false.
ex:
String s=null;
if(s!=null && s.length())
This doesnt throw exceptions and also in most cases you save one more if check.
If the conditions are in the same order, they are exactly the same in terms of efficient.
if (command.equals("sort") && args.length == 2)
Will drop out if command.squals("sort") returns false and args.length will never be checked. That's the short-circuit operation of the && operator.
What it comes down to is a matter of style and readability. IMO When you start chaining too many together in a single if statement it can get hard to read.
Actually, it is called [Lazy_evaluation]: http://en.wikipedia.org/wiki/Lazy_evaluation
That's not really the question but note that if you want the two if evaluated, you can use & :
if (methodA() & methodB()) {
//
}
instead of
boolean a = methodA();
boolean b = methodB();
if (a && b) {
//
}
yeah, their suggestions are completely right. What I suggest you is to write the first check as:
"sort".equals(command)
Maybe it does not make sense in this case but in future. Use the static type first so you never need a null check before
For my work I have to develop a small Java application that parses very large XML files (~300k lines) to select very specific data (using Pattern), so I'm trying to optimize it a little. I was wondering what was better between these 2 snippets:
if (boolean_condition && matcher.find(string)) {
...
}
OR
if (boolean_condition) {
if (matcher.find(string)) {
...
}
}
Other details:
These if statements are executed on each iteration inside a loop (~20k iterations)
The boolean_condition is a boolean calculated on each iteration using an external function
If the boolean is set to false, I don't need to test the regular expression for matches
Thanks for your help.
One golden rule I follow is to "Avoid Nesting" as much as I can. But if it is at the cost of making my single if condition too complex, I don't mind nesting it out.
Besides you're using the short-circuit && operator. So if the boolean is false, it won't even try matching!
So,
if (boolean_condition && matcher.find(string)) {
...
}
is the way to go!
The following two methods:
public void oneIf(boolean a, boolean b)
{
if (a && b)
{
}
}
public void twoIfs(boolean a, boolean b)
{
if (a)
{
if (b)
{
}
}
}
produce the exact same byte code for the method body so there won't be any performance difference meaning it is purely a stylistic matter which you use (personally I prefer the first style).
Both ways are OK, and the second condition won't be tested if the first one is false.
Use the one that makes the code the more readable and understandable. For just two conditions, the first way is more logical and readable. It might not be the case anymore with 5 or 6 conditions linked with &&, || and !.
I recommend extracting your expression to a semantically meaningful variable and then passing that to your evaluation. Instead of:
if (boolean_condition && matcher.find(string)) { ... }
Assign the expression to a variable, then evaluate the variable:
const hasItem = boolean_condition && matcher.find(string)
if (hasItem) { ... }
With this method, you can keep even the most complex evaluations readable:
const hasItem = boolean_condition && matcher.find(string)
const hasOtherThing = boolean_condition || boolean_condition
const isBeforeToday = new Date(string) < new Date()
if (hasItem && hasOtherThing && isBeforeToday) { ... }
Java uses short-circuiting for those boolean operators, so both variations are functionally identical. Therefore, if the boolean_condition is false, it will not continue on to the matching
Ultimately, it comes down to which you find easier to read and debug, but deep nesting can become unwieldy if you end up with a massive amount of braces at the end
One way you can improve the readability, should the condition become longer is to simply split it onto multiple lines:
if(boolean_condition &&
matcher.find(string))
{
...
}
The only choice at that point is whether to put the && and || at the end of the previous line, or the start of the current.
I tend to see too many && and || strung together into a logic soup and are often the source of subtle bugs.
It is too easy to just add another && or || to what you think is the right spot and break existing logic.
Because of this as a general rule i try not to use either of them to avoid the temptation of adding more as requirements change.
If you like to be compliant to Sonar rule squid:S1066 you should collapse if statements to avoid warning since it states:
Collapsible "if" statements should be merged
The first one. I try to avoid if nesting like that, i think it's poor style/ugly code and the && will shortcircuit and only test with matcher.find() if the boolean is true.
In terms of performance, they're the same.
But even if they weren't
what's almost certain to dominate the time in this code is matcher.find(string) because it's a function call.
Most would prefer to use the below one, because of "&&".
if (boolean_condition && matcher.find(string)) {
...
}
We normally called these as "short-circuit (or minimum evaluation)". It means the 2nd argument (here it is "matcher.find(string)") is only evaluated only if the 1st argument doesn't have sufficient information to determine the value of the expression. As an example, if the "boolean_condition" is false, then the overall condition must be false (because of here logical AND operator). Then compiler won't check the 2nd argument which will cause to reduce the running time of your code.
I have such code:
if(object != null && object.field != null){
object.field = "foo";
}
Assume that object is null.
Does this code result in nullPointerException or just if statement won't be executed?
If it does, how to refactor this code to be more elegant (if it is possible of course)?
&& does short circuit while & would not.
But with simple questions like this, it is best to just try it (ideone can help when you don't have access to a machine).
&& - http://ideone.com/LvV6w
& - http://ideone.com/X5PdU
Finally the place to check for sure would be the JLS §15.23. Not the most easy thing to read, the relevent section states:
The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.
Java does have short circuit evaluation, i.e. your code should be ok
One way to know it! Test it! How? Well, make a method which prints out something:
public static boolean test(int i)
{
System.out.println(i);
return false;
}
...
if (test(1) && test(2) && test(3))
{
// not reached
}
This prints:
1
So the answer on your question is "no".
Best way to find out would be try it, especially for a single line question. Would have been faster, too.
The answer is that Java will not execute the body of the "if".
This will not throw any NullPointerException . The condition will be evaluated from left to right and the moment first false expression is found it will not evaluate remaining expression.
Maybe this other question helps you:
Differences in boolean operators: & vs && and | vs ||
Java has short circuit evaluation, so it will be fine.
The code looks ok to me, but do you actually need to check object.field != null? I think that test can be omitted as you never use the variable, just set it.
On a side-note, most programmers wouldn't access fields directly (object.field) but rather through getters/setters (object.setField(x);). Without any more context to go on, I can't say if this is appropriate in your case.
&& and || conditions stops at the point they can decide whether the condition is true/false, in your case, the condition will stop right after object != null and I think that your code is just fine for this case
If you want all of your boolean expressions evaluated regardless of the truth value of each, then you can use & and | instead of && and ||. However make sure you use these only on boolean expressions. Unlike && and ||, & and | also have a meaning for numeric types which is completely different from their meaning for booleans.
http://ibiblio.org/java/course/week2/46.html
Although short circuiting would work here, its not a guarantee that (like I have done many times) you'll get the order wrong when writing another, it would be better practice to nest those if statements and define the order you want the boolean checks to break:
if(object != null)
{
if(object.field != null)
{
object.field = "foo";
}
}
This does exactly the same as you're essentially saying, if the first boolean check fails don't do the second; it is also nullPointerException safe as object.field will not be checked unless object is not null
Using short-circuiting on booleans can become annoying later on as when you have a multiple bool if statement it becomes trickier to efficiently debug which part short circuited.
I recently profiled some code using JVisualVM, and found that one particular method was taking up a lot of execution time, both from being called often and from having a slow execution time. The method is made up of a large block of if statements, like so: (in the actual method there are about 30 of these)
EcState c = candidate;
if (waypoints.size() > 0)
{
EcState state = defaultDestination();
for (EcState s : waypoints)
{
state.union(s);
}
state.union(this);
return state.isSatisfied(candidate);
}
if (c.var1 < var1)
return false;
if (c.var2 < var2)
return false;
if (c.var3 < var3)
return false;
if (c.var4 < var4)
return false;
if ((!c.var5) & var5)
return false;
if ((!c.var6) & var6)
return false;
if ((!c.var7) & var7)
return false;
if ((!c.var8) & var8)
return false;
if ((!c.var9) & var9)
return false;
return true;
Is there a better way to write these if statements, or should I look elsewhere to improve efficiency?
EDIT: The program uses evolutionary science to develop paths to a given outcome. Specifically, build orders for Starcraft II. This method checks to see if a particular evolution satisfies the conditions of the given outcome.
First, you are using & instead of &&, so you're not taking advantage of short circuit evaluation. That is, the & operator is going to require that both conditions of both sides of the & be evaluated. If you are genuinely doing a bitwise AND operation, then this wouldn't apply, but if not, see below.
Assuming you return true if the conditions aren't met, you could rewrite it like this (I changed & to &&).
return
!(c.var1 < var1 ||
c.var2 < var2 ||
c.var3 < var3 ||
c.var4 < var4 ||
((!c.var5) && var5) ||
((!c.var6) && var6) ||
((!c.var7) && var7) ||
((!c.var8) && var8) ||
((!c.var9) && var9));
Secondly, you want to try to move the conditions that will most likely be true to the top of the expression chain, that way, it saves evaluating the remaining expressions. For example, if (c1.var4 < var4) is likely to be true 99% of the time, you could move that to the top.
Short of that, it seems a bit odd that you'd be getting a significant amount of time spent in this method unless these conditions hit a database or something like that.
First, try rewriting the sequence of if statements into one statement (per #dcp's answer).
If that doesn't make much difference, then the bottleneck might be the waypoints code. Some possibilities are:
You are using some collection type for which waypoints.size() is expensive.
waypoints.size() is a large number
defaultDestination() is expensive
state.union(...) is expensive
state.isSatisfied(...) is expensive
One quick-and-dirty way to investigate this is to move all of that code into a separate method and see if the profiler tells you it is a bottleneck.
If that's not the problem then your problem is intractable, and the only way around it would be to find some clever way to avoid having to do so many tests.
Rearranging the test order might help, if there is an order that is likely to return false more quickly.
If there is a significant chance that this and c are the same object, then an initial test of this == c may help.
If all of your EcState objects are compared repeatedly and they are immutable, then you could potentially implement hashCode to cache its return value, and use hashCode to speed up the equality testing. (This is a long shot ... lots of things have to be "right" for this to help.)
Maybe you could use hashCode equality as a proxy for equality ...
As always, the best thing to do is measure it yourself. You can instrument this code with calls to System.nanotime() to get very fine-grained durations. Get the starting time, and then compute how long various big chunks of your method actually take. Take the chunk that's the slowest and then put more nanotime() calls in it. Let us know what you find, too, that will be helpful to other folks reading your question.
So here's my seat of the pants guess ...
Optimizing the if statements will have nearly no measurable effect: these comparisons are all quite fast.
So let's assume the problem is in here:
if (waypoints.size() > 0)
{
EcState state = defaultDestination();
for (EcState s : waypoints)
{
state.union(s);
}
state.union(this);
return state.isSatisfied(candidate);
}
I'm guessing waypoints is a List and that you haven't overridden the size() method. In this case, List.size() is just accessing an instance variable. So don't worry about the if statement.
The for statement iterates over your List's elements quite quickly, so the for itself isn't it, though the problem could well be the code it executes. Assignments and returns take no time.
This leaves the following potential hot spots:
The one call to defaultDestination().
All the calls to EcState.union().
The one call to EcState.isSatisfied().
I'd be willing to bet your hotspot is in union(), especially since it's building up some sort of larger and larger collection of waypoints.
Measure with nanotime() first though.
You aren't going to find too many ways to actually speed that up. The two main ones would be taking advantage of short-circuit evaluation, as has already been said, by switching & to &&, and also making sure that the order of the conditions is efficient. For example, if there's one condition that throws away 90% of the possibilities, put that one condition first in the method.