I'm doing the oracle certified associate Java SE7 Programmer practice exams (the book) and came across a question, and I don't understand the answer even with the explanation.
Here's the explanation and the code:
It will print 3. The loop body is executed twice and the program will print 3.
I don't understand how the loop body is executed twice, maybe I don't understand what the b=!b means. Can someone explain please?
class TestClass {
public static void main(String args[]){
boolean b = false;
int i = 1;
do{
i + + ;
} while (b = !b);
System.out.println(i);
}
}
b = !b is an assignment which assigns the inverse of b to itself (effectively flipping between true and false)
in java, an assignment returns what was assigned (so that a=b=1 is possible)
therefore while (b=!b) will flip the value of b, and then check the value of b.
b=!b
Will always be true, why?
Because, what you are doing is that you insert to "b" the opposite value (T->F, F->T),and if there was no problem while (b = !b); will return TRUE....
So at your case while (b = !b); will always return true
Iteration 1
boolean b = false;
int i = 1;
do{
i++ ; // i = 2
} while (b = !b); // b = !false = true so one more execution
Iteration 2
do{
i++ ; // i = 3
} while (b = !b); // b = !true = false so loop breaks
So it will print 3. simple :)
Actually the confusion is with = sign. = is assigning operator where as == is the conditional operator. The first will assign the value whereas later will check for the condition. You can play with it and have some other result like
int a = 6;
int b = 10;
System.out.println(a = b);
System.out.println(a == b);
and you will get the idea.
At the end of the first iteration the variable i will be 2 because of the increment operator. The expression b=!b will result to true (b = !false) and set the variable b to true as well. So the loop gets executed again.
At the end of the second iteration the variable i is now 3. The expression b=!b will result to false (b = !true), which will be also the value of the variable b. So the whole do-while-loop terminates and the println() statement shows 3.
Keep in mind: = (assign operator) is not the same as == (equality check).
The condition
b = !b;
uses the assignment operator, which returns the value that has been assigned.
Initially, b is false, and therefore true is assigned to b, and used for the condition. The while loop therefore executes a second time. In this execution, b is true, and therefore false is assigned to b and used for the loop condition. The loop therefore exits.
Related
I was going through some exercises but I am confused in this one:
public static int f (int x, int y) {
int b=y--;
while (b>0) {
if (x%2!=0) {
--x;
y=y-2;
}
else {
x=x/2;
b=b-x-1;
}
}
return x+y;
}
What is the purpose of b=y--?
So, for example, x=5 and y=5
when we first go inside of while loop (while (b>0)) will b = 4 or 5? When I am running the code in my computer b is 5. And the return is 3. It is really unclear to me. Sorry if I am unclear in my question.
int b=y--; first assignes b=y and then decrements y (y--).
Also take a look at the prefix/postfix unary increment operator.
This example (taken from the linked page) demonstrates it:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
The difference between a post-increment/decrement and a pre-increment/decrement is in the evaluation of the expression.
The pre-increment and pre-decrement operators increment (or decrement) their operand by 1, and the value of the expression is the resulting incremented (or decremented) value. In contrast, the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation.
In other words:
int a = 5;
int b;
b = --a; // the value of the expression --a is a-1. b is now 4, as is a.
b = a--; // the value of the expression a-- is a. b is still 4, but a is 3.
Remember that a program must evaluate expressions to do everything. Everything is an expression, even just a casual mention of a variable. All of the following are expressions:
a
a-1
--a && ++a
System.out.println(a)
Of course, in the evaluation of expressions, operator precedence dictates the value of an expression just as the PEMDAS you learned in grade school. Some operators, such as increment/decrement, have side effects, which is of course great fun, and one of the reasons why functional programming was created.
I believe b would equal 5 entering the loop because
b=y--;
When the "--" is behind the variable it decrements it after the action.
It's poor coding, as it can confuse new programmers.
The function, assuming it is passing by value, like in the example above (as opposed to passing by reference) takes a copy of y, decrements it, and assigns it to b. It does not alter the argument passed to the function when it was called.
Post increment
x++;
x += 1;
Post decrement
x--;
x -=1;
Pre increment : ++x;
Pre decrement : --x;
According to the Head First Java:
Difference between x++ and ++x :
int x = 0; int z = ++x;
Produces: x is 1, x is 1
in x = 0; int z = x++;
Produces: x is 1, z is 0
I understand that the values of the two would be the same (say 3 to 4). However, does the computer see the two as the same, and would they both be considered expressions?
Thanks in advance!
Yes to both, except that (value++) evaluates to the old value, whereas (value = value + 1) evaluates to the new value.
The direct equivalent of (value = value + 1) within an expression is (++value).
Note that neither of them are thread-safe.
For added fun, here are two more equivalent options:
value += 1;
value -= -1;
That's incorrect. Rather, ++value is the same as value=value+1.
++Value is a pre-increment. Value++ is a post-increment.
'Post' means after - that is, the increment is done after the variable is read. 'Pre' means before - so the variable value is incremented first, then used in the expression.
For example:
int i, x;
i = 2;
x = ++i;
// now i = 3, x = 3
i = 2;
x = i++;
// now i = 3, x = 2
No, my friend ++value is equivalent to value=value+1 as it is changing the new value preincrement operator
and value++ is changing the old value which is kept in the memory i.e. post incrementing it
I have written a piece of Java code which is running in an infinite loop.
Below is the code:
public class TestProgram {
public static void main(String[] args){
Integer i = new Integer(0);
Integer j = new Integer(0);
while(i<=j && j<=i && i!=j){
System.out.println(i);
}
}
}
In the code above, while seeing the condition in the while loop, at first it looks like that program will not go inside the while loop. But actually it is an infinite loop and keeps printing the value.
What is happening here?
i <= j is evaluated to true, because auto unboxing happens for int
comparisons and then both i and j hold the default value, 0.
j <= i is evaluated to true because of the above reason.
i != j is evaluated to true, because both i and j are
different objects. And while comparing objects, there isn't any need of
auto unboxing.
All the conditions are true, and you are not changing i and j in loop, so it is running infinitely.
Because you are comparing
0 < = 0 (true) // unboxing
0 > = 0 (true) // unboxing
reference != secondReference (true) as you are creating objects, not a primitive comparison. So it evaluates to while(true) { // Never ending loop }.
The integer objects are different. It is different from the basic int type.
See this answer: How to properly compare two Integers in Java?
The i != j part is true, which you were expecting to be false.
There are two different cases which we have to understand first,
case 1:
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((i<=j && j<=i && i!=j));
System.out.println(i!=j);
case 2:
Integer i = 10;
Integer j = 10;
System.out.println((i<=j && j<=i && i==j));
System.out.println(i==j);
both are different, as
in case 1: i!=j will be true because both referencing to two different object in heap and can't be same. But
in case 2: i==j will be true because both 10 are integer literals and Java maintains pool for Integer literals which have value (-128 <= X <= 127). So, in this case 10<=127 results true, So both will have reference to same object.
The loop is not ending because your condition is true( i != j is true because there are 2 different objects, use Integer.valueOf instead) and inside the loop the values are not changing so your condition remains true forever.
Perhaps the reason is that both 'i' and 'j' are objects, and object comparison is not the same as object reference comparison. Please consider using !i.equals(j) instead of i!=j
The integer objects are different. It is different from the basic int type.
so you can just do like that. what you do it's just compare the object and of course the result is true.
Integer a = new Integer(0);
Integer b = new Integer(0);
The <= and >= comparisons will use the unboxed value 0, while the != will compare the references and will succeed since they are different objects.
Even this will also works i,e
Integer a = 1000; Integer b = 1000;
but this doesnot :
Integer a = 100; Integer b = 100;
The reason is because Integer internally uses caching for Integer objects between -128 and 127 and return instances from that cache for the range it covers. I am not sure but I guess you can also change its maximum value in package "java.lang.Integer.IntegerCache.high".
For better understanding check url : https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
The program keeps on displaying the same value of i because you aren't incrementing or decrementing either the value of i or j. The condition in the for always keeps evaluating to true, so it is an infinite loop.
you have to know its a bit different in && this and this & when you use && then when first condition is true then it check second condition if its false then it not checked third condition because in & operator if one condition is false all of the statement is false if use || then if it see true then it return true in your code because i and j is equal first and second condition are true then in third condition it will be false because they are equal and while condition is false .
I was asked to write a swap without using temp variables or using xor and i came up with this.
In Java, this works, but in C/C++ this does not work.
I was under the impression that this would always work since the value of 'a' on the left side of the '|' would be stored in a register and then the assignment to 'a' would occur negating the effect on the assigned value for 'b'.
int a = 5;
int b = -13;
b = a | (0 & (a = b));
You are modifying a variable and reading its value without an intervening sequence point.
b = a + 0 * (a = b);
// reading a's value modifying a
This is undefined behavior. You have no right to any expectations on what the code will do.
The C/C++ compiler optimizes the expression 0 * (a = b) to simply 0 which turns your code fragment into:
int a = 5;
int b = -13;
b = a;
In C/C++, assigment are performed in the order of expression. In Java, assignments occur last regardless of other expressions.
e.g. This increments in C but does nothing in Java.
a = a++;
Is following true in java:
In java if you use || then after getting first true condition it neglects the rest conditions. That is If you write if(a || b || c) in java and java finds a is true then it will not check for b and c, just go into the if case.
Yes this is called short circuiting, if you put less expensive checks to the left you might avoid the expensive ones to follow.
This works for || and &&
one of the best uses is checking a value from an object that might be null:
if(myList != null && myList.size() > 6)
the previous line is null safe, reversing the condition will cause a null pointer exception in case myList is null
This is correct. || is called short-circuit OR evaluation, or an OR-ELSE operator.
This is important in situations when evaluating the right-hand side may cause an undesirable consequence:
if (myString == null || myString.indexOf("hello") != -1)
...
would crash if it were not for short-circuiting.
Yes, This way the compiler avoids unnecessary checking and calculation overhead.
That's correct, and that's not just laziness on part of the language implementation, but rather it is a crucial feature - short-circuiting allows you to write something like this:
if (myarray.length > 10 && myarray[10] == 5) { /* ... */ }
Here the second condition may only even be evaluated if the first one is true. Thanks to short-circuiting, if the first condition is false the second is never touched.
YES
(AFAIK)
The same things applies to && but in reverse manner.(for first false).
The same rule as in circuits for AND and OR gates.
Yes, it's called short-circuiting. It also will short circuit &&, i.e.
if (a && b && c)
If a is false then the condition cannot be true, neither b nor c are checked.
This can be problematic if you call methods that return booleans. To get around this, you can use bitwise & and |.
Yes it is correct. If you use | this operator to check OR condition then it checks rest all conditions. It also applied on AND(&) operator.
Yes, and one important thing, if you do any operations in the second part, they will not be made. For example:
int a = 5;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 5
//b = 5
BUT in case:
int a = 3;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 4
//b = 5
I tried to make a simple example, but sometimes you call a method in the second part, (which will not be called if first part was true in case of ||), or the first part was false in case of &&