Chained ANDs or chained ORs best practice - java

Which is better in terms of best practice / efficiency?
if (x == 1
&& y == 1
&& z == 1)
{ do things }
or
if (x != 1 ||
y != 1 ||
z != 1)
{ don't do things and go to a different bit of logic.}
Is there any difference in efficiency when short circuiting ANDs and ORs? Is it (generally) better to check positively or negatively when multiple logical assertions need to be made?

For pure optimization of the code it depends case-by-case. The scenario that will on average do the least amount of comparisons.
For code design it is also case-by-case. The if-cases should match what you are actually looking for. A function that tests if a string is inputted correctly for example. (the tests are made up)
public boolean isValidString (string s) {
if (s.isEmpty())
return false;
if (s.length() < 12)
return false;
if (s...)
return false
return true;
}
In this case the most logical approach is the ||. It could be written.
public boolean isValidString (string s) {
if (s.isEmpty() || s.length() < 12 || s...)
return false;
return true;
}
With http://en.wikipedia.org/wiki/De_Morgan%27s_laws this could be rewritten to not and. However it is not what we want to test, even though they yield the same result.
So stick to the logical approach in general cases.

If you think about efficiency then think about how often each case will occur. The most likely one should be put in front so the whole expression is shortcircuited immediately.

Better you use "==" instead of going for "!=".
This is also recommended with PMD.
The following is good and improves redability.
If(true){
//
}else{
//
}
than
If(!true){
//
}else{
//
}

Well, in some JVM implementations boolean values are stored as integers in the JVM. int value 1 meaning true and int value 0 meaning false. Also, comparison logic at processor level is architecture dependent. Some machines might subtract 2 operands, then add and then compare, others might compare byte by byte etc.. So, unless you are looking at a specific hardware architecture (which you shouldn't.. atleast for java programming language), I don't think this matters much..

Related

Cleaner way to write code snippet

I'm new to java and I was wondering if there was an easier way to write
if(a == 10 || b == 10){
//stuff
}
In my mind I tried something like this:
if(a||b == 10){
//stuff
}
because IMO that makes a lot of intuitive sense, but it's not a thing.
if you're only comparing a few values then you might as well proceed with the current approach as there is nothing in place to make it shorter. However, if you're repeating your self many times, then you can create a helper function to do the work for you.
i.e
static boolean anyMatch(int comparisonValue, int... elements){
return Arrays.stream(elements)
.anyMatch(e -> e == comparisonValue);
}
then call it like so:
if(anyMatch(10, a, b)){ ... }
That's not going to work like that. You're checking the value of two variables against a value, which ends up being two checks, if(a == 10 || b == 10).
However, you can modify this check to this code:
if(Arrays.asList(a,b).contains(10))
It results in the same behavior, but this is neither shorter nor easier to read.
Yeah turns out there isn't a way to make it shorter.
No, we can't do it because in case of java, there is no option for comparison of variables like that.
Even you couldn't write like this
if(a||b){ //staff }
but if you would write then you will get this error message
error: bad operand types for binary operator '||'
Not shorter, but more "intuitively" readable:
boolean condA = (a == 10);
boolean condB = (b == 10);
if(condA || condA){
//stuff
}
always keep in mind, the goal isn't to write shortest possible code, but best maintainable code.

can you have two conditions in an if statement

I'm a beginner in coding. I was recently working with to create a chatting programme where a user will chat with my computer. Here is a part of the code:
System.out.println("Hello, what's our name? My name is " + answer4);
String a = scanner1.nextLine();
System.out.println("Ok, Hello, " + a + ", how was your day, good or bad?");
String b = scanner2.nextLine();
**if (b.equals("good"))** { //1
System.out.println("Thank goodness");
} else **if (b.equals("it was good"))** { //2
System.out.println("Thank goodness");
} else **if (b.equals("bad"))** { //3
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
} else **if (b.equals("it was bad"))**{ //4
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
if(age<18){System.out.println("How was school?");}
else if (age>=18){System.out.println("How was work?");}
The conditions of the if statements are in Bold (surrounded with **). In case of first and the second condition I want my application to do same thing. Similarly third and fourth condition. I thought it was possible to somehow group them in if statement.
I tried with below code but it doesn't compile:
if (b.equals("good"), b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad"),(b.equals("it was bad"))) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
Can someone correct it for me?
You can use logical operators to combine your boolean expressions.
&& is a logical and (both conditions need to be true)
|| is a logical or (at least one condition needs to be true)
^ is a xor (exactly one condition needs to be true)
(== compares objects by identity)
For example:
if (firstCondition && (secondCondition || thirdCondition)) {
...
}
There are also bitwise operators:
& is a bitwise and
| is a bitwise or
^ is a xor
They are mainly used when operating with bits and bytes. However there is another difference, let's take again a look at this expression:
firstCondition && (secondCondition || thirdCondition)
If you use the logical operators and firstCondition evaluates to false then Java will not compute the second or third condition as the result of the whole logical expression is already known to be false. However if you use the bitwise operators then Java will not stop and continue computing everything:
firstCondition & (secondCondition | thirdCondition)
Here are some common symbols used in everyday language and their programming analogues:
"," usually refers to "and" in everyday language. Thus, this would translate to the AND operator, &&, in Java.
"/" usually refers to "or" in everyday language. Thus, this would translate to the OR operator, ||, in Java.
"XOR" is simply "x || y but both cannot be true at the same time". This translates to x ^ y in Java.
In your code, you probably meant to use "or" (you just used the incorrect "incorrect solution" :p), so you should use "||" in the second code block for it to become identical to the first code block.
Hope this helped :)
You're looking for the "OR" operator - which is normally represented by a double pipe: ||
if (b.equals("good") || b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad") || b.equals("it was bad")) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
This is probably more answer than you need at this point. But, as several others already point out, you need the OR operator "||". There are a couple of points that nobody else has mentioned:
1) If (b.equals("good") || b.equals("it was good")) <-- If "b" is null here, you'll get a null pointer exception (NPE). If you are genuinely looking at hard-coded values, like you are here, then you can reverse the comparison. E.g.
if ("good".equals(b) || "it was good".equals(b))
The advantage of doing it this way is that the logic is precisely the same, but you'll never get an NPE, and the logic will work just how you expect.
2) Java uses "short-circuit" testing. Which in lay-terms means that Java stops testing conditions once it's sure of the result, even if all the conditions have not yet been tested. E.g.:
if((b != null) && (b.equals("good") || b.equals("it was good")))
You will not get an NPE in the code above because of short-circuit nature. If "b" is null, Java can be assured that no matter what the results of the next conditions, the answer will always be false. So it doesn't bother performing those tests.
Again, that's probably more information than you're prepared to deal with at this stage, but at some point in the near future the NPE of your test will bite you. :)
You can have two conditions if you use the double bars(||). They mean "Or". That means only ONE of your conditions has to be true for the loop to execute.
Something like this:
if(condition || otherCondition || anotherCondition) {
//code here
If you want all of conditions to be true use &&. This means that ALL conditions must be true in order for the loop to execute. if any one of them is false the loop will not execute.
Something like this:
if(condition && otherCondition && anotherCondition) {
//code here
You can also group conditions, if you want certain pairs of them to be true. something like:
if(condition || (otherCondition && anotherCondition)) {
//code here
There is a simpler way.
if (b.contains("good")) {
...
}
else if (b.contains("bad")) {
...
}

Nested if statements vs complex logic in condition

I have the following problem. I need to validate date and time, so it returns false if the day of the week is Tuesday orThursday and the time is between 2:00 and 3:00 PM.
I have two options:
if (appointmentRequest.getDateTime().getDayOfWeek() == DayOfWeek.TUESDAY
|| appointmentRequest.getDateTime().getDayOfWeek() == DayOfWeek.THURSDAY) {
if (appointmentRequest.getDateTime().getHour() == 2) {
return false;
}
}
Option 2:
if ((appointmentRequest.getDateTime().getDayOfWeek() == DayOfWeek.TUESDAY
|| appointmentRequest.getDateTime().getDayOfWeek() == DayOfWeek.THURSDAY)
&& (appointmentRequest.getDateTime().getHour() == 2)) {
return false;
}
What is the best practice in cases like this?
Logically they are equivalent, and computationally there will be negligible difference in the run times.
Always strive for clarity and the one that is going to be more extensible, and simpler to maintain. As a rule of thumb, bear in mind that although you typically write a line of code once, you'll debug it hundreds of times.
My instinct is that the first option fits that. It's easy to set a line break on the second if if you make that choice.
I find your question a bit of a false dichotomy; clarity can be won in other ways, for example by a combination of extracting the common subexpression into a variable and relying on EnumSet:
LocalDateTime dt = appointmentRequest.getDateTime();
if (EnumSet.of(TUESDAY, THURSDAY).contains(dt.getDayOfWeek()) && dt.getHour() == 2) {
return false;
}

Complexity of if statement

I am wondering complexity of following if statement
if (isTrue()) //case 1
VS
if(isTrue()==true) //case 2
And isTrue defined as
boolean isTrue(){
//lots of calculation and return true false based on that.
return output;
}
I was thinking, complexity of if (isTrue()) is lower then if(isTrue()==true) because on case 2 require additional comparison for equals.
What about space complexity?
Any different thought?
Both of them are same in speed/space. But second way is weird for C/C++ programmers.
The different is, second way is just less readable.
They are equivalent. And when doing global optimizations condition is removed altogether.
The second case (checking for ==true) can get problematic if you or someone else redefines the value of true.
Let's say that we have the following C code:
#define true 2
bool isEqual(int a, int b)
{
return (a == b);
}
if (isEqual(5, 5)) {
printf("isEqual #1\n");
}
if (isEqual(5, 5) == true) {
printf("isEqual #2\n");
}
The output from this code will be
isEqual #1
So the shorter form where you leave out ==true is preferable not only because it leads to less verbose code but also because you avoid potential problems like these.

Difference between String.isEmpty() and String.equals("")

I created a "Color Chooser" with three textboxes where the user defines rgb values.
To check if values entered are correct (only numbers between 0-255) I'm using the following:
public Color getColor() {
if (tfRed.getText().equals("") || tfGreen.getText().equals("") || tfBlue.getText().equals("")) {
return new Color(0, 0, 0, 0);
} else {
if (tfRed.getText().matches("\\d+") && tfGreen.getText().matches("\\d+") && tfBlue.getText().matches("\\d+")) {
// ...
} else {
return new Color(0, 0, 0, 0);
}
}
}
What I'm asking: is it better to use String.isEmpty()? I never found a satisfying answer and I've always wondered if there is any difference.
I think isEmpty() is a bit more efficient. However a smart compiler may optimize the equals("") call anyway. From the OpenJDK source:
671 public boolean isEmpty() {
672 return count == 0;
673 }
1013 public boolean equals(Object anObject) {
1014 if (this == anObject) {
1015 return true;
1016 }
1017 if (anObject instanceof String) {
1018 String anotherString = (String)anObject;
1019 int n = count;
1020 if (n == anotherString.count) {
1021 char v1[] = value;
1022 char v2[] = anotherString.value;
1023 int i = offset;
1024 int j = anotherString.offset;
1025 while (n-- != 0) {
1026 if (v1[i++] != v2[j++])
1027 return false;
1028 }
1029 return true;
1030 }
1031 }
1032 return false;
1033 }
Also the answer here on whether to use str.isEmpty() or "".equals(str) is spot on:
The main benefit of "".equals(s) is you don't need the null check (equals will check its argument and return false if it's null), which you seem to not care about. If you're not worried about s being null (or are otherwise checking for it), I would definitely use s.isEmpty(); it shows exactly what you're checking, you care whether or not s is empty, not whether it equals the empty string
Yes, use String.isEmpty(). It is cleaner (semantically) (performance is also slightly better, but that would be unnoticable) If the instance can be null, use commons-lang StringUtils.isEmpty(string)
Since isEmpty() checks if the length of the String is 0 and "" is the only String with length 0, each String for which isEmpty() returns true would also return true to .equals(""). So technically, they do the same thing.
There might be a minimal difference in performance, but I wouldn't bother about that at all (I'd be very surprised if it were noticeable in production code).
Another difference is if you wrote "".equals(someString), then it would be "null-safe". In other words: if someString was null, this construct would simply evaluate to false and not throw a NullPointerException. If, however, you have someString.equals("") then this would not apply.
The most important difference is how it's read: isEmpty() makes the intention very clear: you want to treat empty strings differently. .equals("") is ever so slightly less clear ("if that string equals that other string, that happens to be empty").
Typically, I like to use equals but in reverse, ie:
"".equals(someString);
Null-safe :)
But yeah, isEmpty() is a simpler operation but not so much that I see it making any significant performance contribution (unless you are writing embedded real-time stuff).
With myString.equals(""), first the compiler creates an String object (it is equivalent to myString.equals(new String("")).
So, isEmpty() should be a better option (although equals("") is very popular).
In theory, it is. For isEmpty(), only the internal metadata of the string has to be looked at (e.g., it's length). For the comparison, you would expect slightly more case differentiations happening.
In practice, it does not matter. You would not observe the speed difference.
Rule of thump: Use the method that is best understood / most readable by the programmer. If it is a test for empty string, I think isEmpty() fits that purpose best.
isEmpty() is faster because it only compares the length integer field in String class to 0 while comparing to an empty string will at best compare references (similar speed) and at worst - run a loop with 0 iterations.
But the biggest difference is readability - isEmpty() is shorter and easier to grasp. BTW I wish there was an isBlank() shorthand for .trim().isEmpty()...
One more reason using myString.equals("") or myString.length() == 0 is that String#isEmpty() method was introduced in Java 1.6.
So arguments to do not use String#isEmpty() can be compatibility reasons with previous versions of Java.
It's partly a matter of history and legacy uses. isEmpty() was only added in JDK 6:
/**
* Returns <tt>true</tt> if, and only if, {#link #length()} is <tt>0</tt>.
*
* #return <tt>true</tt> if {#link #length()} is <tt>0</tt>, otherwise
* <tt>false</tt>
*
* #since 1.6
*/
public boolean isEmpty() {
Before that, everyone compared with "" to see if an String was empty or not. Old habits die hard, so loads of people keep using the "" comparison.
Of course, as mentioned by someone else already, if you use "".equals(someString) then it's automatically null safe. Many people combine the idea of isEmpty with null safeness, by making a static isEmpty method.
isEmpty was only introduced in 1.6. Check Since tag in javadoc.
Therefore, if you are compiling for 1.5 and lower equals("") is your only choice.
However, if version compatibility is not of your concern, I would use isEmpty. As Bozho pointed out it is semantically cleaner ( and a bit faster ).
I had always used .isEmpty()... until today, when I discovered that it does not exist in Java 5.
So :
In Java 6 and newer, we have the choice, and I recommend using .isEmpty(), it is easier to write and clearer to read.
In Java 5 and older we have to use .equals("").
String.equals("") is bit slower than just an isEmpty() call. Strings store a count variable initialized in the constructor, since Strings are immutable.
isEmpty() compares the count variable to 0, while equals will check the type, string length, and then iterate over the string for comparison if the sizes match.
So to answer your question, isEmpty() will actually do a lot less! and that's a good thing.

Categories

Resources