Java "&" vs "|" while statement issue - java

I'm new to Java as of the past day or two and I've been messing around making some very basic programs. I have the following code as a simple number guessing program
public class GUESS2 {
public static void main(String args[])
throws java.io.IOException {
//This program will have you solve a numeric puzzle using different hints as you get closer
int answer='5', guess=0, i=0;
char ignore;
do{
i++;
System.out.print("Can you guess the number I'm thinking of???");
guess = (int) System.in.read();
if(guess==answer) System.out.println("CORRECT!!!");
if(guess >answer) System.out.println("Too high!");
if(guess <answer) System.out.println("Too low!");
do{
ignore=(char) System.in.read();
}while (ignore != '\n');
} while(answer!=guess && i != 5);
}
}
My issue here is with the "while" statment. I want it to exit this loop when EITHER answer=guess or i=5. When I use | or || it gives me the opposite and ONLY exits when I do answer=guess and i=5 at the same time which seems backwards to me.This current code using "&&" works when EITHER answer=guess or i=5 which doesn't make sense to me.
Again I'm a beginner and I appreciate you guys taking the time to help me- probably something simple but I've messed with it for a while.

Let's consider the possibilities. First, with OR(||) operator:
(answer != guess || i != 5)
If answer is equal to the guess, answer != guess evaluates to false, which, based in what you described, should make the program exit. However, i != 5 will still be true, so the whole statement will evaluate to true, making the program keep going, while the statement is true.
If answer is equal to the guess, and i == 5, both will evaluate to false, and, as none of them are true, the OR will evaluate to false, making the loop exit.
Now, with AND(&&) operator:
(answer != guess && i != 5)
If answer is equal to the guess, answer != guess evaluates to false, and, as it is an AND operator, which requires both to be true, the statement will evaluate to false, making the loop exit. If i is equal to 5, i != 5 evaluates to false, and, as already said, will make the statement evaluate to false, and the loop exit.
Hope to have helped.
EDIT: A link I found, may help you, see the 8th item.

If you want to exit the loop when either A or B is true, then you want to stay as long as this isn't the case: when both A and B are false. Which is just how your code reads.

The && gives you the behaviour you want because it requires both of those conditions to evaluate to true in order to continue. This means that if answer equals guess (the first conditions fails), or i equals five (the second condition fails), the loop will exit. However, with the || operator, you're saying continue on as long as either one of these is true. They're known as logical and and logical or, respectively. This should help:
a && b -> if both are true, evaluates to true, otherwise false
a || b -> if either are true, evaluates to true, otherwise false

it does not make sense because you did not read the things in a right way:
What you are asking for is: keep on looping until either answer == guess OR i ==5
However, this piece of code actually means:
do{
} while(answer!=guess && i != 5);
"keep on looping if both answer is not guess and i != 5"
which essentially mean the same thing. The reason you find it counter-intuitive is because you are thinking of the "stopping condition" while do-while loop is specifying the "continuation condition"
Some languages (not Java) do provide do-until loop, which is doing what you want. It may look like this if it is provided in Java:
do {
} until (answer == guess || i == 5)

Related

How to put 2 condition in one statement actiolistener in java? [duplicate]

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")) {
...
}

String comparison (using "or" in a "do while loop") java

I cannot for the life of me figure out why this code loops indefinitely when "turnOrder" is set to "first." It seems to be something about the "or" operator in the "do while loop." But I have no idea how to properly format it.
String turnOrder;
do {
Scanner to = new Scanner(System.in);
turnOrder = to.nextLine();
if ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder))) {
System.out.println("Type your answer as 'first' or 'second.' Without the punctuation.");
} else {}
} while ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)));
It loops cause when you type "first", it returns false in
!"first".equalsIgnoreCase(turnOrder), BUT
it return true in
!"second".equalsIgnoreCase(turnOrder))
false OR true = true, so it will keep looping
You should always reduce your logic operations to their simplest form.
"((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)))"
can be simplified using De Morgan's Laws to
!("first".equalsIgnoreCase(turnOrder) && "second".equalsIgnoreCase(turnOrder))
Of course turnOrder cannot be "first" and "second" simultaneously. It will always evaluate to true, thus your while loop will loop indefinitely.
while ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)))
This statement will always be true until you come up with a turnOrder value that equalsIgnoreCase-s to "first" and "second" simultaneously. Good luck with that! Perhaps you meant...
while (
!(
"first".equalsIgnoreCase(turnOrder) ||
"second".equalsIgnoreCase(turnOrder)
)
)

check for a condition in a do loop in java

I created a simple do while loop where I want to check a condition ( that the number of characters will be 2 and that both of the characters will be equal).
For some reason if I use the loop with || operator it works and if I use the loop with && operator it doesn't work.
I found it hard to understand why the condition works with || and not with &&.
Any idea?
String check;
do {
int num = (int)(Math.random()*200)+10;
System.out.println(num);
check = String.valueOf(num);
} while (check.charAt(0) != check.charAt(1) || check.length() != 2 );
Probably you've missed to apply a negation somewhere.
If you want to convert your ||-based expression to a &&-based expression, then you'll have to do:
while (!(check.length() == 2 && check.charAt(0) == check.charAt(1)));
Note that, in order to avoid an ArrayIndexOutOfBoundsException, I'm switching the pieces of the expression, so that we first check the size of the String, after which we test the first two characters for equality.
Your condition for stopping is length is 2 and both characters are equals.
That means: stop when (check.length() == 2 && check.charAt(0) == check.charAt(1)) Note that it's always better to first check the length since && is a short-circuit operator and otherwise if check's length is smaller than 2, you'll get an exception.
Now, since the condition for the do-while loop is for when to continue looping, you want to negate that (tell the loop when to continue, not when to stop). So you want: !(check.length() == 2 && check.charAt(0) == check.charAt(1)).
You can leave it at that, or you can use De-Morgan's law and convert it to a ||-expression: !(A && B) =~ !A || !B so for your condition that would be !(check.length == 2) || !(check.charAt(0) == check.charAt(1)) which is equivalent for check.length != 2 || check.charAt(0) != check.chatAt(1), which is the condition you wrote that works. Since all transitions are iff (if and only if), you can see the equivalent to your || condition.
If you use an AND condition (i.e. while (check.charAt(0) != check.charAt(1) && check.length() != 2 )) the loop will exit if either condition fails. Both the first AND second conditions must be true for the loop to continue. So if you hit a 2-digit number the loop will exit even if the first two characters match. Similarly if you get a 3 digit number where the first two digits match, the loop will exit. Is this the intended logic?

How to use 'or' in Java?

I'm quite new to Java, and can't figure out how to use 'or'. What is the Java equivalent?
I've already tried && and || but eclipse does not recognise it.
This is part of my code:
if (action.equals ("run") || ("sprint")) {
System.out.println("you ran");
}
else {
System.out.println("else");
}
I've already tried && and || but eclipse does not recognise it.
That's very strange, but just to cover the basics: Let's assume you have the variable a and it contains the value 5. Then:
if (a == 5 || a == 7)
...will be true, because the first part of the expression (a == 5) is true. So the statement "a equals 5 or a equals 7" is true.
The || operator can only be used, in Java, where a boolean (true or false) expression is expected, such as in an if statement like the above. So pretty much in an if or a conditional operator (that ?...: thing, sometimes called the ternary operator).
Re your edit, the problem is that both sides of your || operator aren't true or false ("boolean") expressions. Your statement:
if (action.equals ("run") || ("sprint")){
breaks down like this:
if (
action.equals ("run")
|| // ("or")
("sprint")
)
the second part of that isn't a true/false, it's a string. The correct way to express that in Java (or nearly any other programming language) is:
if (action.equals ("run") || action.equals ("sprint")){
Now both sides of the || result in true/false exprssions:
if (
action.equals ("run")
|| // ("or")
action.equals ("sprint")
)
The reason for this is that the second part may have nothing whatsoever to do with action, and so the compiler can't assume you mean to re-use it in the second part of the expression. You might, for instance, want to use || with two completely unrelated things:
if (action.equals("run") || somethingElse.equals("run")) {
Ok. ("sprint") is not a Boolean expression. Since a if condition expects a Boolean expression your code returns an error. You should change the line with:
if (action.equals ("run") || action.equals("sprint")){
The equals method returns a boolean and the || operator wants two booleans on each side.
You're doing an action.equals("run") on one side but then a ("sprint") on the other which isn't a boolean expression.
Change your code like so:
if (action.equals("run") || action.equals("sprint")){

question on this java code segment

The following code is claimed to use a do loop with a flag to repeat input until a valid int is obtained.
do
{
try
{
// attempt to convert the String to an int
n = Integer.parseInt( s );
goodInput = true;
}
catch ( NumberFormatException nfe )
{
s = JOptionPane.showInputDialog( null,
s + " is not an integer. Enter an integer" );
}
} while ( !goodInput );
I am a little confusing about the logic here. If the Integer.parseInt just works fine, or there is no exception occuring, then the "goodInput" is assigned to "true" at line of
goodInput = true;
Then the !goodInput will be evaluated as False, so the while loop will continue again. This seems to me contradicts to the designed logic, i.e., the while loop should stop after performing a correct parse operation. What is wrong with my analysis above.
do { } while(x); loops while x == true, i.e. until x == false.
Therefore, do { } while(!x); loops while x == false, i.e. until x is true.
Then the !goodInput will be evaluated as False, so the while loop will continue again.
No - when the expression evaluates to false, then the loop stops.
Try to read it as normal English: "do (stuff) while (expression) is true".
A do/while loop behaves exactly like a normal while loop, except it is guaranteed to run at least once. It is best to think of it in those terms.
If it parses it correctly, goodInput is true, which makes !goodInput false, so the loop will end.
The do-while will stop looping when the condition (!goodInput in this case) evaluates to false. As long as it's true it will continue looping.
All analysis of yours are correct. Only when the while statement evaluation is false as you say, it won't loop again.
!goodInput must be false to terminate the loop. If goodInput is true, then !goodInput is false, so the loop terminates.

Categories