String.equals() argument ordering - java

I recently received a downvote for using the following in a recent answer:
String word = ...;
if ("s".equals(word) || "y".equals(word)
The downvote was given due to using a "yoda condition". I asked for further explanation but none was provided. I prefer this style to avoid a possible NullPointerException.
Is this a poor coding style? If so, why?

Bill Pugh asked this question at Devoxx 2011. The vast majority of people went for the form "xyz".equals(str). I am with Bill, now preferring str.equals("xyz").
It's fundamental to the Java tradition that we find errors as early as reasonably possible. NPEs are exceptionally common. We want to route these nulls out as soon as possible.
If you're expecting the reference to maybe null, then I don't particularly object to the backwards notation. It's nice to be explicit and easier to understand that there may be a null with a separate null check, but the reverse order should be well understood and sufficiently differentiate the code from the normal case where null is forbidden.
Working in security, some of the bugs null-tolerance accommodates are vulnerabilities.

Yoda conditions (i.e. putting a constant before a variable in a comparison) can be considered bad practice as it makes the line of code less comprehensible. In this specific case however I would state that using a Yoda condition makes the code more comprehensible as you don't have to put a extra null check in front of it.

Visit the following link to understand what is meant by Yoda Conditions|Notation
Its not a "poor coding style" its diferent way of coding.
Yoda can be usefull to track typos in some languages, i believe the -1 was not deserved to be honest but that is my personal opinion.
But Yoda can be bad as explained in this lengthy but very interesting article.
End of the day, there are supporters in favor and against this kinda of notation.

Well, it depends. If in your program "word" should never be null, word.equals("s") may actually be better. If for some obscure reason "word" will become null, you will get NullPointerException.
Think about it. If you get exception, you know something went wrong, and you can faster find mistake and fix it. If program will continue to work silently, and produce wrong results, it will be much harder to detect the problem. Actually, you may not notice there is the problem at all.
It all depends.

There are several reasons not to do it like that, however in the end it depends on you (or the team working on your product) if you think this is bad coding style. Arguments against it are:
Strings are rarely null (and you shouldn't make APIs where they are because people don't expect it)
It feels weird to put the value you are comparing to first
Code style uniformity is important, because this way is the exception, you should only do it, if everyone in your team does it.
As said I don't think these arguments are very strong, nor is the reason to do it like you. So it is mostly important to just agree on one way as your coding style and stick to that.

TL;DR; This definitely is poor coding style NOT :D
well, the yoda conditions are useful in languages where non-boolean can evaluate to a boolean value, e.g.
int test = 0;
if ( test ){ /* do something */
but this is not allowed in Java so you don't run into problems such as forgetting '=', e.g.
if ( test = 2 ){ /* do something */
instead of test == 2
the compiler will not let you do this. So the yoda condition may seem unnatural to someone who has not had to care about this (because he/she didn't use any other language but Java).
This definitely is NOT poor coding style it is just not very common to see Java code using it

yoda condition is where oup put the literal in front of the variable.
word.equals("s") is read as "word equals s"
"s".equals(word) a human reads as "s equals word"
Our brains read the first example much better and the code is clearer.
the only reason imho to use yoda conditions is to prevent assignment
as in "if (42 = i)" instead of "if(42 == i)"

You can write
if (word != null && (word.equals("s") || word.equals("y")))
instead of
if ("s".equals(word) || "y".equals(word))
In this case, first one will never cause any NullpointerException, but in my point of view in this case the 2nd one is better, though it is in Yoda Condition

There is a special case pf Yoda conditional I've not seen defended, or attacked, in any of the answers, so I'll add it for reference. This is the style of:
if(0 < x && x <= max) {
A Yoda conditional because the constant (0) is before the variable (x). The argument against Yoda conditionals is that is hinders readability. Contrast that example with the functionally equivalent
if(x <= max && x > 0) {
Do you really think that, non-Yoda variant, is more readable? I don't.
For readability when using ordering relational operators (<, <=, >, >=), I prefer the style of these heuristics:
Use consistent ordering relations: > is consistent with >=, but not with < or <=; < is consistent with <=.
Prefer < and <= to > and >=, as the default is ascending order.
Place conditions that impose a lower bound on the variable before conditions that impose an upper bound, if using < and <=. Do the opposite if using > and >=.
This very often produces a Yoda conditional for the lower bound.

One might argue that you should (unit-)test your code enough to be confident that nulls don't go where they're not supposed to. This should obviate the need for yoda conditions.

Related

Why should I learn "switch case" when "if else" already exists [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Advantage of switch over if-else statement
Why Switch/Case and not If/Else If?
I am currently learning "switch case" in school and am wondering what's the point of learning it when "if else" already exists. "if else" is basically another way of doing "switch case".
Please correct me if i am wrong.
It kinda nostalgic to heard it. Both of them actually 'looked' the same. But is a little bit different when the codes executed.
Firstly, 'switch-case' is about comparing value-only. But 'if-else' could process a boolean expression (which would support much more complex clauses)
If you use general 'if-else' when you have found what you are actually searching for, the process will still run until it has finished processing the last if (but actually it could use jump-technique to have similar mechanism like 'switch-case'.)
It won't happen if you use 'switch-case' because once the value you're searching for has been found, it will break and won't continue to the next case. Also, 'switch-case' is faster-to-process than if else because it only compares defined values (not expression). And 'switch-case' also has a good formatting structure (it's simple, compact, readable and clean).
The more tools you have the better. Flat out the best statement of why you should know both... however a more detailed example -
A switch statement works on a single type of variable of the construct:
variable == value
So for example in C if you were trying to compare something to a few different strings in order to make a decision, you can't do that with a switch. In this case you need to know about the if/else constructs.
However if you have a large number of sequential checks:
var == 1 or
var == 2 or
var == 3 etc
The compiler may take your switch statement and convert it to a jump table, which would end up being faster than a large number of comparisons that an if/else list would be.
You should learn the switch construct because it is a useful tool provided by the C language.
It is not the same as if-else blocks.
In the comments section of your question, there are links to existing StackOverflow answers explaining what the differences are.
Each construct has its strengths and weaknesses, and over time you will learn when it is appropriate to choose one over the other.
You should learn both. While it is technically possible to implement any if / else sequence with a switch and vice versa, it would be extremely bad practice to do this ... in most cases.
So you need to learn the two constructs, understand their strengths and weaknesses, and learn to use your judgement as to when it is appropriate to use each one.
And the mere fact that C and C++ and Java (and C# and Pascal and many other languages) all support switch statements should tell you something about its usefulness ...
Difference between switch-case and if-else constructs:
Switch-case switches on values only, it does not evaluates boolean expressions.
Switch-case offers execution of next cases below it automatically if you don't use break after your case block. This feature is sometimes useful for writing complex code, like "Telephone Dial Plan"
Switch-case are more elegant compared to if-else when the number of comparisons are huge, like in displaying "Menu", etc.

Best practice for testing return value of indexOf

What do you normally write when you're testing for the return value of indexOf?
if str.indexOf("a") < 0
vs
if str.indexOf("a") == -1
Would one method be preferred over the other?
I'm actually posing this question for any function in any language that returns -1 on error.
I normally prefer the < 0 approach, because if the function is extended to return -2 on some other case, the code would still work.
However, I notice that the == -1 approach is more commonly used. Is there a reason why?
I try to implement the general principle that tests for "error conditions" should be as wide as possible. Hence I would use < 0 rather than == -1.
This is a principle I was taught during classes in formal methods during my CS degree.
On a simple if it doesn't matter too much, but on loops it's important to detect any "out of range" condition to ensure that the loop is terminated, and not to assume that the loop termination value will be hit exactly.
Take for example this:
i = 0;
while (i < 10) {
++i;
// something else increments i
}
v.s.
i = 0;
while (i != 10) {
++i;
// something else increments i
}
The latter case could fail - the former case won't.
I would also prefer the <0 approach. The reason why == -1 approach is widely used is because of the fact that the functions would indeed return -1 if the index is missing and the case of "extended function" will never happen, according to Java documentation.
In almost all cases advisable to stick to the Java doc as closely as possibly.
See Java Doc:
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#indexOf%28int%29
... according to it: -1 will be returned.
So I would always check for -1. If you have a specific value to check, its safer to check for that specific value, to protect against future code changes in java api.
For example, if you get a -2, that means that somethings is seriously wrong in your JVM. It doesn't mean "not found". It would be better for code to proceed to and cause an Exception/Error.
According to javadoc indexOf is always supposed to return -1 if character does not occur in sequence
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#indexOf%28int%29
As Sandeep Nair points out the javaDoc explains it, but I want to comment a bit.
Both would work fine and I wouldn't say one is "better" than the other. The reason many people write == -1 is that there is a general convention that search methods return -1 if "stuff cannot be found". We cannot use 0 since they are used as indices in arrays etc.
So, it's a matter of opinion. As long as the convention stays, it doesn't matter.
I'd use -1 simply because I want to check what I'm expecting.
I'm not expecting -2. If I got -2, that'd probably mean I have some issues. Checking what you're expecting is just better than checking what you may expect.

Java : Brackets within the if condition

if ((one.option != two.option) && (one.side == two.side))
I need to check the followng Business Logic above
so i written this way
if((data[0].getData.value()!=data[1].getData.value())
&&(data[0].getAction().value()==data[1].getAction().value()))
Is this correct ??
Assuming data[0] in place of one
getData.value() in place of option shown in the top if condition .
I am concerned about the brackets inside the if condition
It's correct, but personally I wouldn't bother with the brackets in this particular case. I would, however, use more whitespace. I'd write that as:
if (data[0].getData.value() != data[1].getData.value()
&& data[0].getAction().value() == data[1].getAction().value())
If you really want the brackets, I'd write it as:
if ((data[0].getData.value() != data[1].getData.value())
&& (data[0].getAction().value() == data[1].getAction().value()))
I'd normally only include the brackets if I wanted to differentiate between, say,
if ((x && y) || z)
and
if (x && (y || z))
Of course, this is assuming that the values are ones which are appropriate to compare with == and !=. If they're strings or other objects, you should potentially be using equals instead.
Two general comments.
First, consider using tests for this kind of thing, specifically test driven development, where you write the test first, fail it and then only write enough of a test to pass it. Then there will be no mystery whether the code is correct.
This is an exercise that will help you learn that approach.
Second, based on that snippet, it looks like your code could use some refactoring to make the intention clear, for example by putting them into a method with a clear name (in your case probably two) that gets called there. TDD tends to result in that kind of clean code, as long as you take the time to refactor once your tests pass.
Your parentheses are correct.
Your if statement is valid but it is difficult to read. I'd recommend following the advice of others about white-space and assigning the values to variables to improve readability. Well written code shouldn't require comments, it should be self evident what data your working with!

Short IF - ELSE statement

I'm trying to make my code more readable, so I decided to use some short IF statements.
Here's my code which doesn't work ("not a statement"):
jXPanel6.isVisible() ? jXPanel6.setVisible(true) : jXPanel6.setVisible(false);
What's wrong with this? Needs brackets? Where?
The "ternary expression" x ? y : z can only be used for conditional assignment. That is, you could do something like:
String mood = inProfit() ? "happy" : "sad";
because the ternary expression is returning something (of type String in this example).
It's not really meant to be used as a short, in-line if-else. In particular, you can't use it if the individual parts don't return a value, or return values of incompatible types. (So while you could do this if both method happened to return the same value, you shouldn't invoke it for the side-effect purposes only).
So the proper way to do this would just be with an if-else block:
if (jXPanel6.isVisible()) {
jXPanel6.setVisible(true);
}
else {
jXPanel6.setVisible(false);
}
which of course can be shortened to
jXPanel6.setVisible(jXPanel6.isVisible());
Both of those latter expressions are, for me, more readable in that they more clearly communicate what it is you're trying to do. (And by the way, did you get your conditions the wrong way round? It looks like this is a no-op anyway, rather than a toggle).
Don't mix up low character count with readability. The key point is what is most easily understood; and mildly misusing language features is a definite way to confuse readers, or at least make them do a mental double-take.
jXPanel6.setVisible(jXPanel6.isVisible());
or in your form:
jXPanel6.setVisible(jXPanel6.isVisible()?true:false);
The ternary operator can only be the right side of an assignment and not a statement of its own.
http://www.devdaily.com/java/edu/pj/pj010018/
As others have indicated, something of the form
x ? y : z
is an expression, not a (complete) statement. It is an rvalue which needs to get used someplace - like on the right side of an assignment, or a parameter to a function etc.
Perhaps you could look at this: http://download.oracle.com/javase/tutorial/java/nutsandbolts/expressions.html
I'm a little late to the party but for future readers.
From what i can tell, you're just wanting to toggle the visibility state right? Why not just use the ! operator?
jxPanel6.setVisible(!jxPanel6.isVisible);
It's not an if statement but I prefer this method for code related to your example.
You can do it as simple as this, I did it in react hooks :
(myNumber == 12) ? "true" : "false"
it was equal to this long if function below :
if (myNumber == 12) {
"true"
} else {
"false"
}
Hope it helps ^_^

Is it bad practice to change state inside of an if statement?

I wrote some code that looks similar to the following:
String SKIP_FIRST = "foo";
String SKIP_SECOND = "foo/bar";
int skipFooBarIndex(String[] list){
int index;
if (list.length >= (index = 1) && list[0].equals(SKIP_FIRST) ||
list.length >= (index = 2) &&
(list[0] + "/" + list[1]).equals(SKIP_SECOND)){
return index;
}
return 0;
}
String[] myArray = "foo/bar/apples/peaches/cherries".split("/");
print(skipFooBarIndex(myArray);
This changes state inside of the if statement by assigning index. However, my coworkers disliked this very much.
Is this a harmful practice? Is there any reason to do it?
Yes. This clearly reduces readability. What's wrong with the following code?
int skipFooBarIndex(String[] list){
if(list.length >= 1 && list[0].equals(SKIP_FIRST))
return 1;
if(list.length >= 2 && (list[0] + "/" + list[1]).equals(SKIP_SECOND))
return 2;
return 0;
}
It's much easier to understand. In general, having side effects in expressions is discouraged as you'll be relying on the order of evaluation of subexpressions.
Assuming you count it as "clever" code, it's good to always remember Brian Kernighan's quote:
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
...However, my coworkers disliked this very much...
Yes, it is. Not just because you can code it like that, you have to.
Remember that that piece of code will eventually have to be maintained by someone ( that someone may be your self in 8 months )
Changing the state inside the if, make is harder to read and understand ( mostly because it is non common )
Quoting Martin Fowler:
Any fool can write code that a computer can understand. Good programmers write code that humans can understand
There's an excellent reason not to do it: it's makes your code really hard to understand and reason about.
The problem is that the code would generate multiple-WTFs in a code review session. Anything that makes people go "wait, what?" has got to go.
It's sadly easy enough to create bugs even in easy-to-read code. No reason to make it even easier.
Yes, side effects are hard to follow when reviewing code.
Regarding reasons to do it: No, there is no real reason to do it. I haven't yet stumbled upon an if statement that can't be rewritten without side effects without having any loss.
The only thing wrong with it is that it's unfamiliar and confusing to people who didn't write it, at least for a minute while they figure it out. I would probably write it like this to make it more readable:
if (list.length >= 1 && list[0].equals(SKIP_FIRST)) {
return 1;
}
if (list.length >= 2 && (list[0] + "/" + list[1]).equals(SKIP_SECOND)) {
return 2;
}
Borrowed from cppreference.com:
One important aspect of C++ that is related to operator precedence is the order of evaluation and the order of side effects in expressions. In some circumstances, the order in which things happen is not defined. For example, consider the following code:
float x = 1;
x = x / ++x;
The value of x is not guaranteed to be consistent across different compilers, because it is not clear whether the computer should evaluate the left or the right side of the division first. Depending on which side is evaluated first, x could take a different value.
Furthermore, while ++x evaluates to x+1, the side effect of actually storing that new value in x could happen at different times, resulting in different values for x.
The bottom line is that expressions like the one above are horribly ambiguous and should be avoided at all costs. When in doubt, break a single ambiguous expression into multiple expressions to ensure that the order of evaluation is correct.
Is this a harmful practice?
Absolutely yes. The code is hard to understand. It takes two or three reads for anyone but the author. Any code that is hard to understand and that can be rewritten in a simpler way that is easier to understand SHOULD be rewritten that way.
Your colleagues are absolutely right.
Is there any reason to do it?
The only possible reason for doing something like that is that you have extensively profiled the application and found this part of code to be a significant bottleneck. Then you have implemented the abomination above, rerun the profiler, and found that it REALLY improves the performance.
Well, I spent some time reading the above without realising what was going on. So I would definitely suggest that it's not ideal. I wouldn't really ever expect the if() statement itself to change state.
I wouldn't recommend an if condition having side-effects without a very good reason. For me, this particular example took several looks to figure out what was going on. There may be a case where it isn't so bad, although I certainly can't think of one.
Ideally, each piece of code should do one thing. Making it do more than one thing is potentially confusing, and confusing is exactly what you don't want in your code.
The code in the condition of an if statement is supposed to generate a boolean value. Tasking it with assigning a value is making it do two things, which is generally bad.
Moreover, people expect conditions to be just conditions, and they often glance over them when they're getting an impression of what the code is doing. They don't carefully parse everything until they decide they need to.
Stick that in code I'm reviewing and I'll flag it as a defect.
You can also get ternary to avoid multiple returns:
int skipFooBarIndex(String[] list) {
return (list.length > 0 && list[0].equals(SKIP_FIRST)) ? 1 :
((list.length > 1 && (list[0] + "/" + list[1]).equals(SKIP_SECOND)) ? 2 : 0);
}
Though this example is less readable.
Speaking as someone who does a lot of maintenance programming: if I came across this I would curse you, weep and then change it.
Code like this is a nightmare - it screams one of two things
I'm new here and I need help doing the right thing.
I think I am very clever because I have saved lines of code or I have fooled the compiler and made it quicker. Its not clever, its not optimal and its not funny
;)
In C it's fairly common to change state inside if statements. Generally speaking, I find that there are a few unwritten rules on where this is acceptable, for example:
You are reading into a variable and checking the result:
int a;
...
if ((a = getchar()) == 'q') { ... }
Incrementing a value and checking the result:
int *a = (int *)0xdeadbeef;
...
if (5 == *(a++)) { ... }
And when it is not acceptable:
You are assigning a constant to a variable:
int a;
...
if (a = 5) { ... } // this is almost always unintentional
Mixing and matching pre- and post-increment, and short-circuiting:
int a = 0, b;
...
if (b || a++) { ... } // BAD!
For some reason the font for sections I'm trying to mark as code is not fixed-width on SO, but in a fixed width font there are situations where assignment inside if expressions is both sensible and clear.

Categories

Resources