String comparison (using "or" in a "do while loop") java - 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)
)
)

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

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?

Java "&" vs "|" while statement issue

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)

Do while loop comparing Strings

I'm trying to do a "do while" loop with a nested if statement. I'm trying to compare two possible values for a String variable "word". If !word.equals "deeppan or thin" do something, else do something. But its not liking me using the or || comparator .. Any suggestions would be welcome.
do {
word = scan.next();
if ( !word.equalsIgnoreCase( "Deeppan" || "thin" ) ) {
System.out.print("Sorry you must specify a Deeppan or thin base, try again: ");
} else {
break;
}
} while ( true );
equalsIgnoreCase takes a single string argument, not a logical expression. You can combine them with || or && though:
if (!word.equalsIgnoreCase( "Deeppan") && !word.equalsIgnoreCase("thin" ))
You have to do it like this:
if (!word.equalsIgnoreCase("Deeppan") && !word.equalsIgnoreCase("thin")) {
Think about the || which i switched to &&, because the if should only be true, if the value is not the first AND not the second one!
This part is wrong, that's not how you use the boolean || operator, and anyway the logic is incorrect:
if (!word.equalsIgnoreCase("Deeppan" || "thin"))
It should be like this, comparison-operator-comparison, and notice the correct way to state the comparison for the effect you want to achieve:
if (!(word.equalsIgnoreCase("Deeppan") || word.equalsIgnoreCase("thin")))
Or equivalently, using De Morgan's laws (and easier to read and understand, IMHO):
if (!word.equalsIgnoreCase("Deeppan") && !word.equalsIgnoreCase("thin"))
You have a few issues going on. First:
"Deeppan" || "thin"
is attempting to use the boolean "OR" operator to compare two strings. The "OR" operator can only compare boolean results and returns a boolean that is the result of the comparison:
System.currentTimeMillis() == 123455667 || object.equals(this) // both sides are boolean results.
true || false // returns 'false'
But let's pretend for a second that "Deeppan" || "thin" is OK (remember, it isn't) and the compiler knows that you want to compare the two strings. It still leaves the issue that the OR operator returns a boolean result (true or false), which you are then attempting to pass into the method equalsIgnoreCase on the word variable. equalsIgnoreCase takes a String argument, not a boolean. This is the second compilation issue. As has been pointed out, what you need is to check for the conditions separately and OR the result to get the final boolean
if("Deeppan".equalsIgnoreCase(word) || "thin".equalsIgnoreCase(word)) {
// do something
}
("Deeppan" || "thin")
is a boolean expression. equalisIgnoreCase takes a string. Therefore you need to make two seperate calls and OR the (boolean) results

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