Branching efficiency - java

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.

Related

Why can my Java code run?

In Java, if should have {} except when there is only one line under if.
But then, why can the following code run on my computer?
int x=1;
int y=1;
if(x<=4)
if(y>=4)
System.out.println("%%%");
else
System.out.println("+++");
System.out.println("***");
Here is what it looks like on my IDE:
And everything runs good. Here is the result (under it loading other resources, don't care about that. I just modified some of my code to try out the code as soon as possible.)
Java will associate the else to the last candidate if.
Your code (with braces) is equal to
if(x<=4) {
if(y>=4) {
System.out.println("%%%");
} else {
System.out.println("+++");
}
}
System.out.println("***");
A candidate if is matched when there is exactly 1 statement (ending with semicolon) or block between the if and the else.
Thanks for you all and the problem solved.
The point is, if execute the next one statement or block.
Java considers the following code as a whole statement.
`if(y>=4)
System.out.println("%%%");
else
System.out.println("+++");`
And it follows the first if.
The last print is not in the scope of consideration, it's just caused by bad indentation.
This is your code
if(x<=4)
if(y>=4)
System.out.println("%%%");
else
System.out.println("+++");
System.out.println("***");
this is what java thinks
if(Boolean) go to next line
if(Boolean) ok this is false, go to else f

How can I create a if-else loop with two optional conditions

I want my code to be basically like this:
If (something OR something else)
{
Do magical things;
}
else
{
cry me a river;
}
How can I do it so there are two optional conditions, meaning both do not need to be true (just one) in order for the loop to do 'magical' things.
You have almost answered your own question. :)
Type simply:
if((first_logical_value) || (second_logical_value)){
// ... do magical things
} else {
// ... do other things
}
If in case of two false values you don't wont to do anything - skip else part of this statement. You can find things like this searching internet resources, e.g.:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/if.html
http://www.erpgreat.com/java/java-boolean-logical-operators.htm

How to jump in java

I have a code like this
public class Test
{
public static void main(String[] args)
{
continue s;
System.out.println("I am not supposed to print this");
s:
System.out.println("I am suppose to print this");
}
}
I get the error
java: undefined label: s
What is wrong ?
Basically, there is no practical way to do that in Java. You appear to be trying to do the equivalent of a "goto", and that is not supported in Java. The break label and continue label statements can only branch to an enclosing labelled statement.
Now according to the Java formal grammar you could write this:
s: {
continue s;
System.out.println("I am not supposed to print this");
}
System.out.println("I am suppose to print this");
but that still won't compile for two reasons:
The continue is only allowed to branch to a label on a loop statement. (A break doesn't have that restriction ... but ...)
The continue (or a break) makes the next statement unreachable.
See also: Alternative to a goto statement in Java
But there is one rather tricky way to get your code to "work":
static final boolean flag = true; // class attribute ...
...
s: {
if (flag) break s;
System.out.println("I am not supposed to print this");
}
System.out.println("I am suppose to print this");
The "test" there will be evaluated by the compiler so that the break is effectively unconditional. But the JLS says that the first println will be treated as reachable, so that you won't get an unreachable code error.
I guess this might be useful if you are generating this source code. Apart from that, it is (IMO) just a curiosity. It is simpler to do this with a regular if / else statement ... or by deleting the first "print" entirely.
Jumping like this is not possible in Java, only way to jump is from loops, while and do.
What is the "continue" keyword and how does it work in Java?
Read #Heinzi answer
2.2.6 No More Goto Statements
Java has no goto statement. Studies illustrated that goto is (mis)used more often than not simply "because it's there". Eliminating goto led to a simplification of the language--there are no rules about the effects of a goto into the middle of a for statement, for example. Studies on approximately 100,000 lines of C code determined that roughly 90 percent of the goto statements were used purely to obtain the effect of breaking out of nested loops. As mentioned above, multi-level break and continue remove most of the need for goto statements.
The Java Language Environment, James Gosling
and Henry McGilton, 1996
There is no "goto" in java. And "continue" does a little bit other function. You can use "continue" for example in loops like:
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
In the example above, if for example searchMe.charAt(5) != 'p' then the loop will continue from the beginning of loop from i=6, and numPs++; will not be processed.
You can read more about this here:
Branching Statements
continue is a keyword in Java used to skip iterations of a loop.
If you are trying to find an equivalent to GOTO, you should reconsidering how you are trying to solve your problem, GOTO is never a valid option, ever.
As far as I know, there is no goto in Java (there is a keyword, but it has no meaning)
Theoretically, Java have Jump statements return and break.
The return statement jumps out of a method, with or without returning values to the calling statement.
The break statement jumps out of loops.
As mentioned in the earlier answers, goto is not available in Java, and is not considered to be a good programming practice in procedural or object oriented programming. It existed back in the days of sequential programming.

Difference between multiple IF else condition and logical OR operation

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.

While Loop Weirdness in Java

I noticed that java (hence probably C) has no problem with this:
while(condition1) {
//do somethin'
} while(condition2);
Is this the same as:
while(condition1 && condition2) {
//do somethin'
}
No, you have two loops.
while(condition1) {
// do something
}
while(condition2); // second loop which does nothing.
The second loop is the same as
while(condition2) { }
EDIT: My suggestion is to use the automatic formatter in your IDE regularly. Otherwise you can create formatting which suggests the code does things it doesn't.
example 1
if (condition)
statement1;
statement2;
statement3;
In this example, it appears that the first two statements are part of the if condition, but only the first is.
example 2
http://www.google.com/
statement;
Doesn't look like legal Java, but it is, not for the reasons the formatting suggests ;)
No, they are different.
The first while(condition1) will run first.
Then comes while(condition2), which has nothing after it except a single ; which means it's just some empty statement.
Remember that in control blocks like if, for, while, if you don't use the {} braces, then only the first immediate statement after it will be considered part of it.
Example:
if (condition)
System.out.println("hello"); // prints only if condition is true.
System.out.println("no"); // not bound to the 'if'. Prints regardless.
while (condition)
; // do nothing!
System.out.println("something"); // not bound to the while
Edit The empty while loop is mentioned in the Java code conventions
7.6 while Statements
A while statement should have the following form:
while (condition) {
statements;
}
An empty while statement should have the following form:
while (condition);
There is no construct is java as shown in the first form. You have probably seen
do {
} while (cond)
EDIT : You are misreading the first form. There should have been a line break after the }. This confused me as well.

Categories