I have been learning Java for a while now and still learning new syntax tricks and stuff. I came across this in Android source code:
boolean retry = id == 1;
What does it mean?
id == 1 is a boolean expression which is true if id equals 1, and false otherwise.
boolean retry = id == 1; declares a boolean variable named retry, and assigns the value of the boolean expression id == 1 to this variable.
So it declares a boolean variable which is true if id == 1, and false otherwise.
To make it a bit clearer, you might write it that way:
boolean retry = (id == 1);
retry is true if id has the value 1, otherwise retry is false.
It is the same as
boolean retry;
if (id == 1)
retry = true;
else
retry = false;
==, which is the equality predicate, has a higher precedence than =, which is the assignment operator.
Therefore, id == 1 is evaluated first and then its value (either true or false) is assigned to retry.
The boolean retry gets the value of true if id == 1.
It's the same as:
boolean retry;
if (id == 1) {
retry = true;
} else {
retry = false;
}
first the id is evaluated with 1, so presumably id is an integer.
After that, the value retry is assigned this evaluation, so if id is equal to 1, retry will become true, and for any other value of id retry will become false.
This line creates a boolean variable and sets it to true if id is equal to 1 and false if it is not.
I find that just using parens helps to clear up the confusion behind complex statements like this.
boolean retry = (id == 1); Makes much more sense to me. Here it's clear that (id == 1) is an expression being evaluated and the result is being assigned to boolean retry
It is acts like a ternary operation, (x) ? true : false in C, C++, C#, etc;
The similar syntax:
boolean retry = (id == 1)? true: false;
Or it can written another way:
boolean retry;
if (id == 1) {
retry = true;
} else {
retry = false;
}
It might be easier to see whats happening if you look at it like this:
boolean retry = (id == 1);
So basically it checks if id equals 1, and then assigns the result to the variable retry.
It is a way of defining a boolean variable.
When id is 1, the value of retry will be true.
retry assigns an expression which will be either true or false as retry is a boolean.
Further, == will be solved first and then it will be assigned to retry.
It is basically the same as retry = (id == 1). It is evaluating the boolean expression, and assigning it to retry.
The Boolean variable retry will get value 0 or 1 depending on whether the expression id==1 returns true or false.
If value of id is 1, then id==1 will correspond to true, thus retry=1.
And if value of id is 0, then id==1 will correspond to false, thus retry=0.
Please note that == is a comparison operator.
1.int id = 1;
boolean retry = id == 1;
which means retry = true;.
2.int id = 2;
boolean retry = id == 1;
which means retry = false;.
Simplification id == 1 can be consider as
if ( id == 1 ){
}
I will base my response on the assumption that id is an int hence the comparison against 1 is proper and a compilation error is not in place.
== is the equality operator in java as described in section 15.21.1 of the JLS. Being a boolean operator, == will output a boolean value.
= is the java's assignment operator, in this particular case it's the compound assignment operator having the following syntax:
boolean f = (op1 op op2)
In translation = assigns the output value of the (op1 op op2) operation to the left operand, in this case f.
Looking back to your sample, the output of id == 1 (true if id has the value 1, false otherwise) is assigned to retry.
To conclude in plain english, your sample has the following meaning: Retry as long as id has the value 1.
The code can write just like this,then it will be understood easily,do you think
so? Last, thanks you for giving the chance to answer the question!
boolean retry = (id == 1);
Related
This question already has answers here:
Java logical operator short-circuiting
(10 answers)
Closed 6 years ago.
I work on Java 8 and I have a simple issue that I have not figured out.
I have a 3 methods which are validating the data from db and returning true or false based on whether they got a row or not. The tricky part is, even if I know that the first part
is returning false, I still want it to check for the other two methods. I have written my code like this :
boolean flag = true;
flag = flag && validateMethod1();
flag = flag && validateMethod2();
flag = flag && validateMethod3();
return flag;
The issue is, when validateMethod1() returns false, it is not calling validateMethod2(). Can someone explan why ?
I tried this :
boolean flag = true;
flag = flag & validateMethod1();
flag = flag & validateMethod2();
flag = flag & validateMethod3();
return flag;
Still face the same issue.
&& is a short circuited AND operator. It doesn't evaluate the second operand if the first operand is evaluated to false.
In order to evaluate all the operands, use the non-short-circuit version of the AND operator :
return validateMethod1() & validateMethod2() & validateMethod3();
As you can see, your logic can be reduced to a single line of code.
Java uses sort-circuit evaluation of expressions - i.e. as soon as it knows for sure the result will be false, it stops the evaluation.
Since your expression is a conjunction, once flag is found to be false, it is clear the whole expression will be false.
One way around it (quite verbose) is:
boolean flag1 = validateMethod1();
boolean flag2 = validateMethod2();
boolean flag3 = validateMethod3();
return flag1 && flag2 && flag3;
That's because you are using short circuit && instead of &, which leads to check only first argument in this case, when this argument is false.
The & operator, when used as logical operator, always evaluate both sides.
I'm studying some Java at the moment at I've come across the following piece of code. I understand how the typical ternary operator (e.g. the line beginning with "boolean a" below), but I can't understand how to read the expression on the line beginning with "boolean b". Any help on how to read this line would be much appreciated! Thanks!
public class Ternary{
public static void main (String[] args){
int x = 10;
int i = 2;
boolean a = x > 10 ? true: false;
boolean b = a = true ? ++i > 2 ? true:false:false;
System.out.print(b);
}
}
Break it up like this:
true ? (++i > 2 ? true
: false)
: false;
So here the testing condition is always set to true. So the branch of the ternary that executes is the ++i > 2 ? true : false part.
This simply checks to see if after incrementing, i is greater than 2. If so, it will return true. Otherwise it will return false.
This whole expression is actually needlessly complex. It can simply be written as such:
boolean b = a = (++ i > 2);
However, the code is probably logically incorrect since this abstruse expression doesn't make that much sense. Since the previous line sets the value of a, I'm assuming that the next line actually intends to test a. So the actual intent might be:
boolean b = a == true ? ++i > 2 ? true : false : false; //notice the ==
In which case you can break it up as:
(a == true) ? (++i > 2 ? true
: false)
: false;
But you don't need to actually do a == true since a is already a boolean, so you can do:
a ? (++i > 2 ? true
: false)
: false;
Here, it checks to see if a is true. If it is, it performs the check we already went over (i.e., to see if the incremented value of i is greater than 2), otherwise it returns false.
But even this complicated expression can be simplified to just:
boolean b = a && (++i > 2);
Ah! Never write code like that. But I would assume that is not written by you. But you can read it like this:
// I assume that's `a == true` instead of `a = true`
boolean b = a == true ? (++i > 2 ? true : false)
: false;
which can be broken further as:
// a == true is better written as just `a`. You shouldn't do boolean comparison
// like that.
boolean b = a ? (++i > 2) : false;
// If that is really a = true, then you can break it as:
boolean b = a = true ? (++i > 2) : false;
which can be further broken down as:
// If that is `a == true`
boolean b = a && (++i > 2)
// If that is really a = true, then you can break it as:
boolean b = a = (++i > 2);
Also, the first assignment:
boolean a = x > 10 ? true: false;
can also be written as:
boolean a = x > 10;
boolean nu = f=='f' && t=='f'; //0
boolean ei = f=='f' && t=='t'; //1
boolean zw = f=='t' && t=='f'; //2
boolean dr = f=='t' && t=='t'; //3
System.out.println( nu ? 0 : ei ? 1 : zw ? 2 : dr ? 3 : "invalid");
In boolean b = a = true ? ++i > 2 ? true:false:false; the following happens:
a = true
This will give a true value and evaluate to true.
Than we get another condition, ++i > 2 from ++i > 2 ? true:false, which will be also true in this case. The outcome will be true.
Ternary operators are
condition then true or false
The condition is always true (because a equals true).
Then the result is true because ++i is greater than 2 (it's 3).
Therefore, it assigns true to b. If the condition was false, it would assign false. That false would be assigned from the last false.
It would help if you could use parentheses and review that code as follows;
boolean b = a = (true ? (++i > 2 ? true : false) : false);
You can think it as:
if (true) // # If Number:1
{
if (++i > 2) // # If Number:2
{
a = true;
}
else { a = false; }
}
else { a = false; }
Where if(true) is a Tautology and If Number:2 will always be executed. Therefore; it becomes;
if (++i > 2)
{
a = true;
}
else { a = false; }
Which can be evaluated to; a = (++i > 2) ? true : false); and which becomes: a = ++i > 2 as a result b = a which is ++i > 2.
With some guesses at what is being attempted and some renaming of variables, and assuming the a = true was meant to be a == true you get:
boolean failed = result > 10 ? true: false;
boolean b = failed ? ++retries > 2 ? true:false:false;
This can then be tidied up to the much more logical:
boolean failed = result > 10;
boolean giveUp = failed && ++retries > 2;
Horrible code!
There are a couple of clues that the b = a = true ? ... should be b = a == true ? ..., since otherwise the previous line is a useless assignment (a is never read), and the final false of the line becomes unreachable code. The compiler will tell you that.
I'm going to answer assuming a corrected == - but you'll know whether it was a typo on your part, an unreliable source, or a 'spot the bug' test, and be able to use the same techniques on whatever code you like.
The trick is to refactor it step by step. First add brackets and indentation based on precedence rules.
b = a == true ? ++i > 2 ? true:false:false;
... becomes ...
b = (a == true)
? (++i > 2 ? true:false)
:false;
Next note that:
a == true is equivalent to a.
boolean x = a ? true : false; is equivalent to boolean x = a.
Therefore:
b = a
? (++i > 2)
:false;
or:
b = a && ( ++i > 2 );
If this is "serious" code, the way to approach this would be to write a set of unit tests that cover all the possible input cases. Then make these refactorings one at a time, each time re-running the tests to ensure that you've not changed the behaviour of the code.
Notice that there are no true or false literals in the reduced form. Seeing boolean literals in a ternary operation -- or indeed, ternary expressions for boolean values at all -- is a code smell, since the non-ternary version is usually simpler and clearer.
Ternary expressions are very useful for their intended purpose, which is mapping boolean conditions to non-boolean outputs:
shippingPrice = orderTotal >= freeShippingThreshold ? 0 : getStandardShipping();
I have to write the condition for this:
last_page = ((nl.getLength() == 0) -= 1);
In this line am getting following error:
The left-hand side of an assignment must be a
variable
This is my code:
int current_page = 25;
boolean last_page;
int prev_page;
int next_page;
NodeList nl = doc.getElementsByTagName(KEY_SONG);
prev_page = (current_page -= 1);
next_page = (current_page += 1);
the part ((nl.getLength() == 0) evaluates to a boolean value, and you cannot substract 1 from that.
The double == sign is a comparative operator. Basically, you're checking that nl.getLength() is 0. This will give you a boolean value (True or False).
The -= sign means "decrement". So someVar -= 1 will try to subtract 1 from the value of someVar.
You can't subtract a number from a boolean because they are different types. This is the reason you are getting your error.
Because you declare last_page as a boolean and you mention an if statement, I am assuming you want to check to see if you are on the last page. The code to do that would be this:
last_page = (current_page == (nl.getLength() - 1)); //is the current page the last page?
Remember that in Java indexes start at 0 and go until length - 1. This statement will check to see if the current page is the final index of nl
simply use this instead :
last_page = nl.getLength() -1;
The error you are getting is because of this (nl.getLength() == 0) as it will return a boolean true or false and hence you cannot subtract( and any other arithmetic operation like add,multiply, etc.) any number from a boolean it doesn't make sense like this: (true - 1) or (false +1)
Look, (nl.getLength() == 0) is not a variable, it's an expression, just like 1 + 1. The operator -= however is not an expression, it wants to decrement a variable, that is, take the variable's value, modify it and write it back. How could you "write back" into an expression?
The appropriate CS term would be lvalue: a value which you can not only read from, but also write to. Expressions like (nl.getLength() == 0) are not lvalues, however the operators like -= expect an lvalue to be able to modify it. That's what the error message is basically saying.
On the contrary, in your second example current_page is an lvalue.
If i have the following if statement
if ( (row != -1) && (array[row][col] != 10) ) {
....
}
Where row is an int value and array is an int[][] object.
My question is, if this will throw an exception if row = -1 as the array won't have a -1 field, so out of bounds exception? Or will it stop at the first part of the if, the (row!=-1) and because that is false, it will ignore the rest?
Or to be sure it doesn't throw exception, i should separate the above if statement into two?
(Pls, don't tell me to check this out for my self :) I'm asking here 'cause i wanna ask a followup question as well ...)
It will stop safely before throwing an exception
The && is a short-circuiting boolean operator, which means that it will stop execution of the expression as soon as one part returns false (since this means that the entire expression must be false).
Note that it also guaranteed to evaluate the parts of the expression in order, so it is safe to use in situations such as these.
It will not throw an exception. However, if row is < -1 (-2 for example), then you're going to run into problems.
It will stop at the first part of the if. Java uses short circuite evaluation.
No, It wont. the compiler will not check the second expression if the first expression is false... That is why && is called "short circuit" operator...
Called a short-circuit evaluation via the && and if the row check fails, there is no point in continuing evaluation.
Most programming languages short-circuit the test when the first expression returns false for an AND test and true for an OR test. In your case, the AND test will be short-circuited and no exception will occur.
Many programming languages have short-circuit evaluation for logical operators.
In a statement such as A and B, the language will evaluate A first. If A is false, then the entire expression is false; it doesn't matter whether B is true or false.
In your case, when row is equal to -1, row != -1 will be false, and the short-circui the array expression won't be evaluated.
Also, your second question about the behavior of the array index is entirely language-dependent. In C, array[n] means *(array + n). In python, array[-1] gives you the last item in the array. In C++, you might have an array with an overloaded [] operator that accepts negative indexes as well. In Java, you'll get an ArrayIndexOutOfBoundsException.
Also, you might need something like the following (or just use a try/catch).
boolean isItSafe(int[][] a, int x, int y) {
boolean isSafe = true;
if (a == null || a.length == 0 || x >= a.length || x < 0 || y < 0 || y >= a[0].length ) {
isSafe = false;
}
return isSafe;
}
How do you put an if...else statement within a for statement?
This is the code:
// This is within a actionListener. When ever I press a button, this happens.
for (int i = 0; i < booleanVariable.length; i++) {
//length is 8
System.out.println("booleanVariable is" + booelanVariable[i]);
if (booleanVariable[i] = true) {
booleanVariable[i] = false;
System.out.println("booleanVariable was true")
break;
} else {
System.out.println(" booleanVariable is false");
}
}
This is the output over 3 presses:
booleanVariable is true
booleanVariable was true
//correct
booleanVariable is false
booleanVariable was true
//incorrect.
booleanVariable is false
booleanVariable was true
//incorrect
This means that, for some reason, even if booleanVariable is false, the output says is true, which is false.
What I've found:
Without the break; statement, the program goes around the for all 8 times and outputs exactly the same as without a break, only incorrect values another 5 times.
What I've tried:
Changing the if from true to false (out of desperation)
If within a While within a For
else, else if
case switch
Normally, I'd just use a switch, but I'm using booleans, and booleans dont work is switches.
If someone knows the answer, I'd be forever grateful. Thanks.
Change your
if (booleanVariable[i] = true) {
to
if (booleanVariable[i] == true) {
You need to use == operator for comparison. One = sets the value to true which returns always true.
You can also change it to
if (booleanVariable[i]) {
Your problem may be in this line:
if (booleanVariable[i] = true) {
Boolean comparisons should use ==, unless you are intending to set the value to true. In any event, this line will always evaluate to true.
Note also that you never really need to compare to true, you can simply say something like:
if (booleanVariable[i]) {
since if the value is true, the code block will be entered, and if it is false, it will proceed to the else case.
You have to use == to compare the values. Yu use the = that asigns the value true to the variable so it will always be true
if (booleanVariable[i] == true)
There's an error in the if statement --
You are assigning true to the variable, that's why it's outputting true each time.
it needs to be == (equals) not = (assign).
if (booleanVariable[i]) instead of if (booleanVariable[i] = true)....= is assignment operator...you could also use == instead
You should change if (booleanVariable[i] = true) as if (booleanVariable[i] == true).
need '==' instead of '='.