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();
Related
public class FlourPacker {
public static boolean canPack(int bigCount, int smallCount, int goal) {
if ((bigCount < 0 || smallCount < 0 || goal < 0))
return false;
if ((bigCount * 5) < goal)
return ((goal - (bigCount * 5)) <= smallCount);
else return ((goal % 5) <= smallCount);
}
public static void main(String[] args) {
System.out.println(canPack(3, 0, 11));
}
}
So in this problem bigCount is worth 5 and smallCount is worth 1 and I am supposed to try to get the goal number. I can not go over(the goal) with the bigCount but I can with a smallCount.
But my question is, how come in the last if and else statement I don't need to put true or false for the return? when I run it (ie. the main method that I created) it tells me true even though I never put return true in the code.
You don't need to specify true or false specifically. If you did, then all your if-statements would have to be if (true) or if (false).
So, instead, you write an expression inside the if-statement that evaluates to true or false (Taking your example, if ((bigCount * 5) < goal) will be equivalent to into if (true) or if (false) after plugging in the values from the variables).
This same idea goes for return statements (return ((goal % 5)<= smallCount) will become return true or return false).
how come in the last if and else statement I don't need to put true or
false for the return?
The answer is because you return the result of a comparison operation, using relational opertaors. Always a comparison operation will return true or false (boolean values).
For eg : when the (goal - (bigCount * 5)) <= smallCount); is evaluated its output will be always a boolean value (a true or a false!!!). The corresponding return statement will return it to the caller (here it is a print statement). It will be displayed on your console.
Ref : Relational operators
This question already has answers here:
What is the Java ?: operator called and what does it do?
(17 answers)
Closed 7 years ago.
Can anybody tell me how the snippet below will be executed?
Code:-
int a = 3, b = 4;
a = (a > b) ? a : b;
System.out.print(a);
It is the same as
int a = 3;
int b = 4;
if(a > b) {
a = a;
} else {
a = b;
}
System.out.print(a);
Also see
What is the Java ?: operator called and what does it do?
This is a ternary operator (note: not particular to Java but it's widespread and implemented in many languages), and returns either the 2nd or 3rd argument depending on the result of the initial condition.
result = condition ? result if true : result if false
and as such it's shorthand for
if (condition) {
return a;
}
else {
return b;
}
The value of a variable often depends on whether a particular boolean expression is or is not true and on nothing else. For instance one common operation is setting the value of a variable to the maximum of two quantities. In Java you might write
if (a > b) {
max = a;
}
else {
max = b;
}
Setting a single variable to one of two states based on a single condition is such a common use of if-else that a shortcut has been devised for it, the conditional operator, ?:. Using the conditional operator you can rewrite the above example in a single line like this:
max = (a > b) ? a : b;
(a > b) ? a : b; is an expression which returns one of two values, a or b. The condition, (a > b), is tested. If it is true the first value, a, is returned. If it is false, the second value, b, is returned. Whichever value is returned is dependent on the conditional test, a > b. The condition can be any expression which returns a boolean value.
line 1: a and b are defined.
line 2: a is set to the value of b (because 3 is not bigger than 4).
line 3: a is printed to current std out.
If 'a' is greater than 'b' you'll get a = a, otherwise if 'b' is greater than 'a' you'll get a = b.
It is the same as the following:
int a = 3, b = 4;
if(a > b){
a = a;
}else{
a = b;
}
System.out.print(a);
And that could be rewritten as:
int a = 3, b = 4;
if(a <= b){
a = b;
}
System.out.print(a);
The ? is the ternary operator, which considers the code before as condition and evaluates the code before the : is it is true, and the code after : if it is false.
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);
That's my while loop, and the question is, how can i get a true condition?
s and t are Integer variables
while (s<=t && s>=t && s!=t )
EDIT
tl;dr the original question stated:
s and t are int variables (and OP commented they are not Integer variables)
Never!
s and t are int variables, so when s == t the third operand will fail, when s != t one of the first two operands will fail.
Possible, but unlikely, if they are declared as volatile int s, t; in a multi-threaded application.
EDIT
Question has been modified. Now s and t are Integer variables, which makes the answers referring to Integer objects more relevant.
By boxing the primitive value in an object:
Integer s = new Integer(5);
Integer t = new Integer(5);
boolean rslt = (s <= t && s >= t && s != t);
System.out.println("Result = " + rslt);
The rslt boolean here will indeed evaluate to true.
However, the following would return false:
s <= t && s >= t && !s.equals(t)
it is because in Java, for objects, == means that it is indeed the same instance, while equals is left up to be implemented by every class and typically means that the core values of the compared objects are the same -- while not necessarily being the same class instance (AKA object). The > and < for boxed primitives are evaluated agaist the primitive value, however == is checking the object identity.
It actually is possible:
public class EqualsTest
{
public static void main(String[] args)
{
Integer x = new Integer(Integer.parseInt(args[0]));
Integer y = new Integer(Integer.parseInt(args[1]));
if(x <= y && y <= x && y !=x)
{
System.out.println("equal");
}
else
{
System.out.println("not equal");
}
}
}
Compiling this and running it with two equal integer arguments produces:
$ java EqualsTest 5 5
equal
The reason that this works is due to autoboxing and the fact that, for objects, == only checks whether or not the references are the same (which, in the case above, they are not).
Never man, no way.
s<=t && s>=t returns true if s == t, and s == t && s != t returns false forever.
You cant the only way first two conditions result true is when s is equal to t and the third conditions negates this fact.
Hence i dont think its possible
If the two values are accessible by multiple threads (either static, or members variables of an object shared between multiple threads), you could do this:
Thread 1:
s = 1; // 1
t = 1; // 2
t = 2; // 5
Thread 2:
This is equivalent to your expression but easier to label.
boolean result = s <= t; // 3
if(result) {
result = s >= t; // 4
}
if(result) {
result = s != t; // 6
}
Assuming everything happens in the order given by the commented numbers, then at the end of thread 2's code, result will be true.
So, thread 1 sets s and t to be equal, then thread 2 checks that they're equal, then thread 1 sets them to be not equal, then thread 2 checks that they're not equal.
There are more complicated situations where this could be true, but this is the simplest one I could think of.
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.