I'm studying for the OCA Java SE7 Associate exam. One of my practice exam questions had the following code snippets:
boolean flag = true;
if (flag = false) {
System.out.println("1");
}
else if (flag) {
System.out.println("2");
}
else if (!flag) {
System.out.println("3");
}
else
System.out.println("4");
Notice the if (flag = false) conditional. The question asked what the output of this snippet would be. All the numbers were provided as answer choices and then there was a choice that said "compiler error," which is what I selected. I was wrong. The output would be 3. I tested in Eclipse and it also came back with 3.
I then tested with
int x = 3;
int y = 1;
if (x = y) {
// whatever
}
and, of course, got an error.
Why can the flag be changed from true to false inside the if-statement, but the value of x can't be changed in the similar scenario? Is it because flag is a boolean type and x is type int? I Googled this, but was unable to find anything.
Because the assignment of x = y doesn't equate to a boolean evaluation.
if is expecting the result of the operation to give either a true or false return.
Something like if ((x = y) == y) would work (the evaluation would return true)
flag = false is an assignment, so it is carried out. After the assignment on the first if, it evaluates to false because it was just set to it. For equality it should have been flag == false, but since it was an assignment, the top if was evaluated to false, and since it was changed to false, when you get to !flag, that passes because flag is no longer true, and it prints 3.
You got an error with if(x = y) because after the assignment, the value couldn't be evaluated as a boolean outcome whereas if(flag = false) can evaluate to boolean after the assignment.
The big thing to remember about high-level languages is that it takes more than one low-level statement to perform the logic of even a simple if, and with the assignment case, there is a minimum of 2 operations going on, first the assignment, then the equality.
if (flag = false) will set the flag variable to false, then check if(flag).
You are suggesting doing if(x = 1) which could set x to 1, but if(x) is not valid.
It would print 3 because the boolean variable is assigned false (and checked for true) then checked for false and finally for !false which is true.
Related
So, there is a class Hotel, that contains 20 Rooms in form of a matrix 4x5 (4 floors, 5 rooms on every floor). The class Room has the properties:
floorNumber(int),
roomNumber(int),
numberOfBeds(int),
occupation(boolean)
etc.
For occupation, true means busy, and false means free.
One of methods I have to implement in Hotel is the one that reserves a room
reserve(int floorNumber, int roomNumber)
This method should check if occupation is true or false.
If it is true, then reservation fails, and if it is false, I should set occupation to true, with method
setOccupation(boolean t).
Also, method reserve return boolean (true or false), depending on whether reservation succeeded or not.
In that method, you guess, is problem with scope of one variable.
So there it is:
public boolean reserve(int floorNumber, int roomNumber){
boolean flag = false;
for ( int i = 0; i < 5; i++){
if(rooms[floorNumber][i].getRoomNumber() == roomNumber){//every element in matrix rooms has this property: rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
flag = true;
}
else
flag = false;
}
}
return flag;
}
The problem is, when I set (in first line) flag to true, function returns true, and when I set flag to false, function returns false.
The reason I have to assign some value to flag in first line is because compiler shows:
Error: variable flag might not have been initialized
So, the problem is that it seems like method never executes code with for loop.
I know that variables defined in loop don't exist outside loop, but those defined outside should change their values in loop.
Like in this question here:
Java - Access variable inside and outside of for-loop
There is a simpler way to accomplish what you want to do. You don't need a boolean flag at all; you can just return true immediately on success or return false if the entire loop executed without finding a room.
public boolean reserve(int floorNumber, int roomNumber){
for (int i = 0; i < 5; i++) {
//every element in matrix rooms has this property:
//rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getRoomNumber() == roomNumber){
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
return true;
}
}
}
return false;
}
But if you insist on applying your original approach that uses a flag, then: First give it a value of false (in case no room succeeded). When we find an unoccupied room (successful), set it to true. If we find an occupied room, don't touch the flag value.
public boolean reserve(int floorNumber, int roomNumber){
boolean flag = false;
for (int i = 0; i < 5; i++) {
//every element in matrix rooms has this property:
//rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getRoomNumber() == roomNumber){
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
flag = true;
} // else DO NOTHING
}
}
return flag;
}
I found what the problem was.
It was actually index floorNumber in matrix rooms[floorNumber][] that goes from 0 to 3 (there are 4 floors), of course.
But in real life, floor numbers go from 1, and I passed argument to
reserve(int floorNumber,int roomNumber)
without considering that.
So, I just decremented floorNumber by 1 in body of method, and it works now.
Another class is going to pass in random numbers into this method(x,y,z). I want to know the boolean that does returns true from my last if() statement, so I can do operations on it. I have explained my logic in the comments.
I am still really new to this, so my logic may be wrong.
public static String FindDate(int x, int y, int z) {
boolean istrue1 =(x >= 1 && x <= 31);
boolean istrue2 =(y >= 1 && y <= 31);
boolean istrue3 =(z >= 1 && z <= 31);
if(istrue1 ^ istrue2){
if(istrue1^istrue3){
if(istrue2^istrue3){//now knowing that no values are the same, i can find the true value.
if(istrue1||istrue2||istrue3){
// I want to store/use/print/know which bool(istrue) that evaluated to true, so I would know if it is
//x,y,z that went through the algorithm successfully.
}
} else{return "Ambiguous";}
}else{return "Ambiguous";}
}else{return "Ambiguous";}
return "true"; //I would actually end up returning the value that went through the algorithm
}
You can store boolean values just like any other type in Java. I'm not sure exactly what your last comment means by "the value that went through", but if you want to keep track of the result of a particular test, you don't necessarily need to write something like
if (a == b) {
return true;
} else {
return false;
}
In that case,
return a == b;
is equivalent. If the expression is more complicated parens are a good idea.
return ((a == b) || c);
And instead of returning, you could always store the result and do something with it later.
bool test = ((a == b) || c);
action(test);
You can your following: But your condition is incorrect 3 variable for two value (true, false) all can't be different. So your logic always return "Ambiguous"
if(istrue1 ^ istrue2){
if(istrue1^istrue3){
if(istrue2^istrue3){
//now knowing that no values are the same, i can find the true value.
if(istrue1||istrue2||istrue3){
// I want to store/use/print/know the bool that evaluated to true, so I would know if it is
//x,y,z that went through the algorithm successfully.
return "true";
}
}
return "Ambiguous";
Instead of:
if(istrue1||istrue2||istrue3)
Its is easiest to just break it down into 3 differnt if statement.
if(istrue1)
if(istrue2)
if(istrue3)
No easy trick that i was hoping for. sad day.
Also the statements i did with the xor(^) operators turns out to be bad logic.
it would be easiest to this:
if(a&&b || a&&c || b&&c)
That would return ambiguous if any combo are both true.
However thats not the original question, but I thought i might as well mention it.
I'm doing a practice question which is:
We have a loud talking parrot. The "hour" parameter is the current hour time in the range 0..23. We are in trouble if the parrot is talking and the hour is before 7 or after 20. Return true if we are in trouble.
parrotTrouble(true, 6) → true
parrotTrouble(true, 7) → false
parrotTrouble(false, 6) → false
My code is:
`public boolean parrotTrouble(boolean talking, int hour) {
if ((talking = true) && (hour < 7 || hour > 20)){
return true;
}
else
return false;
}`
The correct answer is:
public boolean parrotTrouble(boolean talking, int hour) {
return (talking && (hour < 7 || hour > 20));
// Need extra parenthesis around the || clause
// since && binds more tightly than ||
// && is like arithmetic *, || is like arithmetic +
}
I am wondering what is the difference between talking = true and just talking.
talking = true assigns true to talking and returns true.
if (talking == true) is the same as if (talking), since both return true.
in Java , sign equal represents assignments, double equal represents comparison.
In your case you are assigning instead of comparing.
When you just use talking, it will have same value which is passed as parameter to parrotTrouble method. So value changes as per input.
Whereas talking = true is an assignment which will always evaluate to true.
In java if statement requires result of if condition = true // if(condition)
to be able to execute code inside curly bracket // {}
=> this true you can assign directly i.e if(true)
or it can generated as result of condition i.e if(val==true)
now in your case
when you put talking = true it assign true to talking and return true
and in other code use talking directly which contains value true so it returns true
int MATCH_LENGTH = 0;
int FINAL_MATCH_LENGTH = 0;
int FINAL_MATCH_POS = 0;
while (window.contains(next)) {
int MATCH_POS = window.indexOf(next);
boolean nextMatches = true;
while (nextMatches = true) {
int index = window.indexOf(next);
index++;
int positionOfNext = fileArray.indexOf(next);
positionOfNext++;
MATCH_LENGTH++;
char afterNext = fileArray.get(positionOfNext);
char afterNextInWindow = window.get(index);
if (afterNext != afterNextInWindow) {
nextMatches = false;
if (MATCH_LENGTH > FINAL_MATCH_LENGTH) {
FINAL_MATCH_POS = MATCH_POS;
FINAL_MATCH_LENGTH = MATCH_LENGTH;
MATCH_LENGTH = 0;
}
window.remove(window.indexOf(next));
}
}
}
I am running into an infinite loop here. I think it is because of the nextMatches boolean variable. However, I am not sure how that affects the program, as I have the condition for the while loop as while (window.contains(next)). However, I am removing the occurrences of next one by one, so eventually while (window.contains(next)) will have to return false and the while loop will have to break. My reasoning here might be flawed though with the remove line window.remove(window.indexOf(next));.
Or is some other part of my reasoning flawed?
You made the classic = vs == mistake
while (nextMatches = true)
should be
while(nextMatches)
As a general rule, don't compare booleans to true and false. It just leads to these sort of weird bugs and makes the code less legible in my opinion. If you name your variables properly, Java conventions has booleans sound like a conditional. For example: isEmpty or isFull. This way things read like english: while(isFull)
I'm a bit confused on your logic, especially since int index = window.indexof(next) will not change anything. index will be redefined.
The problem is here while (nextMatches = true) try put instead
while (nextMatches == true)
I found the problem. It was this line: int index = window.indexOf(next);.
I kept on redefining index as the same number over and over again, which caused the infinite loop. Problem solved!
while (nextMatches == true) {
This condition will be false iff nextMatches is assigned with false.
The only place you are assigning it false, is in following code block:
if (afterNext != afterNextInWindow) {
nextMatches = false;
...
Since, while is running infinite for you, it means nextMatches is never assigned with false when code executes, i.e if condition is always false.
This means, that in every iteration of while; afterNext is always equals to afterNextInWindow.
Ok so lets say I have boolean x = false. If I have a loop that says while (!x) does this mean while x is NOT false (true) or while x is NOT true (false)?
EDIT:
Ok I'm a bit confused, I think Im getting different answers. So if I have
int x=0;
boolean add1=false;
while (!add1){
x=1;
}
What is the final value of x in this case?
x=false;
while (!x)
substituting the value of x we have
while(!false)
Now ! is the logical complement operator which inverts the value of a boolean so we get
while(true)
So we keep looping till x is false or till !x is true.
Note that the value of the variable can change in the body of the loop causing the looping to break. Consider a typical search program which uses a boolean variable called found:
found = false; // initialize found to false.
while(!found) { // keep looping till key is not found.
...
if(key is found) {
found = true; // key found...make found true.
}
}
UPDATE:
In your updated question add1 is false initially so !add1 is true so we enter the while loop and change x to 1. Since the value of add1 does not change in the loop and there are no break and return you keep looping infinitely.
The loop will repeat as long as !x is true. In other words, it will repeat as long as x is false.
A boolean condition is always checked for being true. So while (!x) means while x is not true, i.e. while x is false.
Update: The code you posted is an infinite loop since !add1 evaluates to true and this is never changed within the loop.
I feel nobody really (tried to) explain, what it means.
while (!x) does not really mean much. It is only a few instructions for the computer to do. It does not mean things like do stuff while x is true or false or whatever. !x is an expression and in the case that x = false, this expression yields true. The computer actually calculates true by applying ! on the value of x: false.
while(!x) does not mean "run when x equals false." It means something like "run if inverting the truth value of variable x yields true." From experience we know (or learn) that it is about the same as "run only when x equals false". Just like while (!(x && !x)) means(?) "run always". You can see this by trying all possible values of x and remembering those who will make the expression equal true. Some day you will just know what it 'means'.
What it does, how it works, is not what it means, right?
The loop will continue to iterate so long as x = false. If x = true the loop will end.
Let's replace x with red sky. While the sky is not red, red sky = false will evaluate as true.
Asking repeatedly whether the value red sky is not true (as long as the sky stays blue, of course) will cause the loop to repeat.
I think you have a code smell here.
I prefer to have simple while conditions, to keep the code readable. So if you end with a piece of logic that looks like:
boolean is_something = false;
while (!is_something) {
...
}
maybe it's better to reverse both the meaning of the variable and its default value, to get rid of the negation in the while condition:
boolean is_not_something = true;
while (is_not_something) {
...
}
Please note that this is a very general example. Often you don't need to have an explicit negation in the variable name. If you have a variable called is_empty, the opposite doesn't have to be called is_not_empty, it can be called is_full.
while(!add1) runs if add1 is false. Since add1 is always false, x will always equal 1.