I've written the following if-statement in Java:
if(methodName.equals("set" + this.name) ||
isBoolean() ? methodName.equals("is" + this.name) :
methodName.equals("get" + this.name)) {
...
}
Is this a good practice to write such expressions in if, to separate state from condition? And can this expression be simplified?
I would change it to
if (methodName.equals("set" + this.name)
|| methodName.equals( (isBoolean() ? "is" : "get") + this.name)) {
...
}
Is it good practice? It's good if it makes it easier to read. It makes it easier to read if (1) it does and (2) the sort of person who'd be confused by it won't be reading it. Who's going to read it?
Wouldn't something like the following work?
if (methodName.equals("set" + this.name)
|| methodName.equals("get" + this.name)
|| (isBoolean() && methodName.equals("is" + this.name))) {
...
}
It's more readable than the way in which you used the ternary operator and certainly easier to understand. It also has the advantage that it can avoid an unnecessary method call to the isBoolean method (it has either 1, 2 or 4 method calls whereas yours always has either 1 or 3; the performance gain/loss is probably too minute to notice).
Also there's a similar question here titled "Is this a reasonable use of the ternary operator?" One user had the following to say:
The ternary operator is meant to
return a value.
IMO, it should not mutate state, and
the return value should be used.
In the other case, use if statements.
If statements are meant to execute
code blocs.
Do note that I included parentheses around the expression containing '&&' for readability. They aren't necessary because x && y is evaluated before m || n.
Whether you choose to use it is up to you, but I tend to avoid it in favour of readability.
I would be inclined to change it to
if (methodName.equals(setterForThis())
|| methodName.equals(getterForThis())) {
...
}
with some functions extracted:
private String setterForThis() {
return "set" + this.name;
}
private String getterForThis() {
return (isBoolean() ? "is" : "get") + this.name;
}
It's longer of course, but I'm not really into golf anyway.
Related
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")) {
...
}
I have a piece of code that uses a conditional operator to compare the value of the variable x to 5:
(x >=5 ? x : -x)
What benefit is there to using a conditional operator over a regular if else statement?
Note that is ?: is an expression - it returns a value which must be consumed
z = (x >=5 ? x : -x)
The if construct in Java is not an expression (there are languages where it is) and does not return a value so in this sense they are not equivalent.
An example where they are equivalent is when the if options perform an assignment:
if("Cheese".equals(x)) {
type = "Dairy";
} else {
type = "Maybe not dairy";
}
this is the same as
type = "Cheese".equals(x) ? "Dairy" : "Maybe not dairy";
You can nest ?: to arbitrary depth but really shouldn't - it becomes quite difficult to read:
List<String> cheeses = Arrays.asList("Gouda", "Edam");
String x= "Gouda";
String type = cheeses.contains(x) ? "Gouda".equals(x) ? "Yummy Gouda" : "Cheese - but not Gouda" : "Maybe not dairy";
Ternary operator is not the equivalent of if-else in EVERY possible case. This is because both of possible results of using ternary operator are return values (e. g. simple printing to the console is not a return value so it can't be one of possible results in ternary operator).
Look, you can do it with if-else, but it's not possible with ternary operator:
if (x > 5) {
System.out.println("Statement is true");
else {
System.out.println("Statement is false");
}
You can't do it with ternary operator:
x > 5 ? System.out.println("Statement is true") : System.out.println("Statement is false");
When both of results of using ternary operator are considered as return values, they are then an equivalent of if-else.
Yes, it can be used, but off course in that case using -x doesn't make sense so it depends on what do you want to return when String is an input. You can do this:
("Cheese".equals(x) ? <some object of expected type X> : <some other object of expected type X>)
where X can be String on any other type. And remember to do "string".equals(x) instead of x.equals("string"). This prevents NullPointerException.
For primitive values you can use ==, but for objects you need to use equals method. There are some edge cases when you can use == on String, but they are not relevant to your case I guess and you can read about it outside of this topic.
PS: Some answers talk about if else statement, but that's not what question is about.
Can this be used like an if else on all accounts? For example, can you
compare strings with it?
I am pretty sure that by saying like an if else he means conditional operator which has if else like behaviour, not if else instruction itself.
Yes it can be used in Java; however note that x =="Cheese" isn't the proper way to compare strings in Java, you want something like "Cheese".equals(x).
Since I started programming Java, I've noticed that everyone was using && and || instead of & and |. What is the reason for this? I've been using && and || all this time because I didn't know you can use & and | on booleans.
class A{static{
boolean t = true;
boolean f = false;
System.out.println("&ff " + (f&&f) + " " + (f&f));
System.out.println("&ft " + (f&&t) + " " + (f&t));
System.out.println("&tf " + (t&&f) + " " + (t&f));
System.out.println("&tt " + (t&&t) + " " + (t&t));
System.out.println("|ff " + (f||f) + " " + (f|f));
System.out.println("|ft " + (f||t) + " " + (f|t));
System.out.println("|tf " + (t||f) + " " + (t|f));
System.out.println("|tt " + (t||t) + " " + (t|t));
}}
As far as I can tell, they are the same:
$ javac A.java && java A
&ff false false
&ft false false
&tf false false
&tt true true
|ff false false
|ft true true
|tf true true
|tt true true
Exception in thread "main" java.lang.NoSuchMethodError: main
Does using || and && improve my code in any way?
As a simple test, I replaced hundreds of occurrences with the short form, and all of my unit tests still pass.
|| and && uses short circuit evaluation
From same article
Short-circuit evaluation, minimal evaluation, or McCarthy evaluation
denotes the semantics of some Boolean operators in some programming
languages in which the second argument is only executed or evaluated
if the first argument does not suffice to determine the value of the
expression
Consider you have an object and you want to check one of its property for some value if you do:
if(obj != null & obj.ID == 1)
If your object obj is null you will get a null reference exception, since you used single &, the first condition evaluate to false, but it will still continue to the next condition and raising null reference exception.
If you used && then the second condition will never get evaluated, thus no exception.
if(obj != null && obj.ID == 1)
With your code you will not see any difference, but using bitwise | or & with multiple conditions would result in no short circuiting at all.
More Explanation.
consider that you following code:
Boolean conditionA = 2 > 1; //some condition which returns true
if(conditionA | obj.SomeTimeConsumingMethod()){
}
Now in above code snippet, suppose you have an object with a method SomeTimeConsumingMethod which takes a lot of time in processing and returns true or false. If you use single | it would evaluate both the conditions, since first conditionA is true it will process obj.SomeTimeConsumingMethod as well. End result will be true for the whole if statement since | (OR) is used.
If your condition is using double || (OR Logical operator)
if(conditionA || obj.SomeTimeConsumingMethod())
Then the second condition obj.SomeTimeConsumingMethod() will not be evaluated. This is short circuiting and that just saved you from executing some time consuming method. Still the end result is true regardless of what was returned from obj.SomeTimeConsumingMethod().
As has already been pointed out, && and || do short-circuit evaluation. & and |, with boolean operands, do the same operations but evaluate both operands regardless of the value of the first operand.
There are cases where it matters which you use, such as when the left operand is a pre-condition for exception-free evaluation of the right hand operand.
In most cases, it does not matter. I use && and || in those cases for readability, because that is the commoner choice. Using & or | with boolean operands would tend to make most Java programmers have to stop and think, and ask themselves whether there is some specific reason for it. I suspect it may be so common because of the inheritance from C and C++.
|| is logical or, where | is the bitwise operation or. Same with && and &. Use && and || if you're in an if statement, and | or & if you're doing bit operations.
While you may get the "correct" result using the bit-wise operators, understand they do NOT represent the same thing. For instance, this works
public static void main(String[] args){
int x = 5;
int y = 9;
System.out.println(x&y); // prints "1"
}
However, this won't
public static void main(String[] args){
int x = 5;
int y = 9;
System.out.println(x&&y); // Compile error: java: operator && cannot
// be applied to int,int
}
The reason you don't use bit-wise operators for boolean logic is so that it's clear what the code is trying to do (as well as knowing that it actually works). Bit-wise operators are for manipulating bit values, where as boolean operators are for evaluating first-order logic statements.
While not the same, it is along the same reasoning for using .equals() vs == for comparison -- You don't want readers guessing as to what you meant to do. It may work in some instances (like comparing constant, hard-coded strings with ==), but it is poor form because what it says is that you are asking for instance equality as opposed to value equality, which is usually implied. And using bit-wise operators implies you want to do bit manipulation, not first-order logic evaluation.
Arguing that short circuit evaluation is mandatory because of performance is weak. You can make an argument that is almost as weak: that short circuit evaluation encourages extra nondeterminism and side channels. Random optimizations or random loss of nondeterminism/side channels, I'd prefer the latter.
The only remaining argument is this: If your code base relies on short circuit behaviour, e.g., the trick described by Habib (if (obj != null && obj.ID == 1)), then it may not be a good idea to start mixing in &, because programmers might get it confused with &&. i.e., if you use &/| everywhere, but only use && in a few places where you rely on short circuit evaluation, someone might make an error and put only &, it may be hard to spot. In this case, if you relied on && for performance instead of something like null checking, it may be harder to spot when someone accidentally puts & alone, since there would be no stacktrace.
Does using || and && improve my code in any way?
Let me demonstrate two examples on how the conditional boolean operators may improve your code. Compare
if (a != null && a.equals("b") || z != null && z.equals("y"))
System.out.println("correct");
with
boolean b1 = a != null, b2 = z != null;
if (b1) b1 = b1 & a.equals("b");
if (b2) b2 = b2 & z.equals("y");
if (b1 | b2) System.out.println("correct");
which is the best way I can think of relying solely on the logical boolean operators.
Second, say you have two tests to perform: simpleTest() and heavyTest(), where the latter involves making an HTTP request and parsing the response. You have
if (simpleTest() & heavyTest()) System.out.println("success");
else throw new IllegalStateException();
and want to optimize it. What would you rather do, this:
if (simpleTest()) {
if (heavyTest()) System.out.println("success");
else throw new IllegalStateException("operation could not be completed");
} else throw new IllegalStateException("operation could not be completed");
this:
boolean b = simpleTest();
if (b) b = b & heavyTest());
if (b) System.out.println("success");
else throw new IllegalStateException("operation could not be completed");
or this:
if (simpleTest() && heavyTest()) System.out.println("success");
else throw new IllegalStateException();
Why should I always use || instead of | and && instead of &?
You shouldn't always use them, but you would do yourself a favor by making them your default because in 99.9% of uses they either don't hurt or make your code much better. Reserve the logical operators for that 0.1% of cases where you truly do need their semantics.
It has been mentioned elsewhere on this page that relying on the conditional evaluation of the right operand makes for counterintuitive code. I refuse to accept such a view on intuition because, by definition, intuition is a learned skill. It is a facility bestowed to you by evolution to recognize a pattern in situations you encounter often, and to quickly (and subconciously) cut through to the correct conclusions. One of the most important aspects of learning a language is acquiring the right intuitions. The argument that a language feature is bad because it is counterintuitive to someone who looks at it for the first time cannot be taken seriously.
In Java (and C/C++ if I remember correctly) the single "|" and "&" are bit-wise operators, not logical operators, they are used for completely different things.
You use the "&&" and "||" for boolean statements
You use the "&" and "|" for bit operations, given the following are binary numbers
dont make assumption so fast. It because this wont compile:
static boolean f(boolean a) {
boolean x = (true|a) ? a : x;
return x;
}
Bro.java:6: variable x might not have been initialized
boolean x = (true|a) ? a : x;
^
and this will:
static boolean f(boolean a) {
boolean x = (true||a) ? a : x;
return x;
}
&& and || are short cut operators. For example:
A && B
Condition B will not be evaluated if condition A is false
A || B
Condition B will not be evaluated if condition A is true
You should always use shortcut operators for multiple conditions evaluation. | or & are used for bit-wise operations.
I've been getting an "illegal start of expression" error when trying to compile this for loop inside a if statement in java. Does anyone have any idea why?
if(letter.equals(" ") || letter == null ||for(String a: array){ letter.equals(a);})
Try
if( letter == null || letter.equals(" ") || checkArray(array, letter))
{
...
}
boolean checkArray(String[] arryay, String letter)
{
for(String a: array)
if(letter.equals(a))
return true;
return false;
}
Note: checking letter for null after you have already called equals() does not make too much sense; i've reordered those.
You cannot. Perhaps you should move the if statement into the for statement?
As rfausak said, a for statement does not return a boolean. You should have made that an answer by the way.
If you use a Set you could write:
if ( (letter.equals(" ")) || (letter == null) || (a.contains(letter)) ) {}
Well, that´s because you can not have a for loop within an if condition. It seems you want to see if the letter is within the array array; if so then you can do it with Apache commons-lang's ArrayUtils:
ArrayUtils.contains( array, letter );
This wont work because a for doesn't evaluate to a boolean. For readabilities sake you should extract that to a method anyway, good examples appear in other answers.
Other points, you should rejig your conditionals to not be susceptible to NullPointerExceptions
if (letter == null || " ".equals(letter) || arrayContains(array, letter)) {
//...
}
If you are able to add additional libraries, there are some nice apache commons libraries to make this work easier, namely StringUtils in commons-lang and CollectionUtils in commons-collections.
You also may like to harden that input checking if it's possible to get Strings larger than one character, by using String#trim() after checking for null. Again, this would be a good candidate for an extracted method isBlank(String str).
How come this is not possible? I am getting illegal start of expression.
(s1.charAt(i) == ' ') ? i++ : break;
The thing to understand here is that the ?: operator is used to return a value. You're basically calling a function that looks like this in that line:
anonymous function:
if(s1.charAt(i) == ' '):
return i++;
else:
return break;
Makes no sense, right? The ?: operator was only designed as a shorthand for if/else return statements like the above, not a replacement of if/else altogether.
You cannot use break in part of a ternary conditional expression as break isn't an expression itself, but just a control flow statement.
Why not just use an if-else construct instead?
if (s1.charAt(i) == ' ') {
i++;
} else {
break;
}
The ternary operator is an expression, not a statement. Use if ... else ... for this.
Of course it works. But it's an operator. Since when was a statement such as 'break' an operand?
I recommend avoiding the ternary (?:) operator EXCEPT for simple assignments. In my career I have seen too many crazy nested ternary operators; they become a maintenance headache (more cognitive overload - "don't make me think!").
I don't ban them on my teams, but recommend they are used judiciously. Used carefully they are cleaner than a corresponding if/else construct: -
public int ifFoo() {
int i;
if( isSomethingTrue()) {
i = 5;
}
else {
i = 10;
}
return i;
}
Compared to the ternary alternative: -
public int ternaryFoo() {
final int i = isSomethingTrue()
? 5
: 10;
return i;
}
The ternary version is: -
Shorter
Easier to understand (my opinion, of course!)
Allows the variable to be "final"; which simplifies code comprehension; in a more complex method, someone reading the code knows no further code will try and modify the variable - one thing less to worry about.