2

It executes correctly the first time, but:

  1. It keeps printing "Please try again (Y/N)?" no matter what the input is after asking to continue.
  2. I am unsure if != is appropriate to use for String comparison. I want to say while loopChoice "is not" Y or N, keep asking.

    while(isLoop) {
        // Ask for user input
        System.out.print("Enter hours worked: ");
        hoursWorked = scn.nextInt();
    
        System.out.print("Enter rate per hour: ");
        payRate = scn.nextInt();
        scn.nextLine();
    
        // Call functions to compute stuff
        ...
    
        // Print results
        ...
    
        System.out.print("\nDo you want to continue (Y/N)? ");
        loopChoice = scn.nextLine().toUpperCase();
    
        while(loopChoice != "Y" || loopChoice != "N") {
            System.out.print("\nPlease try again (Y/N)? ");
            loopChoice = scn.nextLine().toUpperCase();
        }
    
        switch(loopChoice) {
            case "Y":
                isLoop = true;
                System.out.print("\n");
                break;
    
            case "N":
                isLoop = false;
                System.out.println("Terminating program...");
                scn.close();
                System.exit(0);
                break;
    
            default:
                System.out.println("Your input is invalid!");
                isLoop = false;
                System.out.println("Terminating program...");
                scn.close();
                System.exit(0);
                break;
        }
    }
    
k_rollo
  • 5,304
  • 16
  • 63
  • 95

5 Answers5

2

You should compare with String equals

while (!loopChoice.equals("Y") && !loopChoice.equals("N"))

Also, replace the or operator with and operator

Nipun Talukdar
  • 4,975
  • 6
  • 30
  • 42
1

That's not how you compare strings in Java.

There is also a logical error in your code, as the string can't be both Y and N at the same time, you have to use && instead of ||. As long as the choice is neither Y or N, you want to continue the loop. If it is any of them, you want to stop. So && is the correct choice here.

To check if two strings are equal, you have to use .equals(obj)

while (!loopChoice.equals("Y") && !loopChoice.equals("N")) {

The reason for this is that == compares object references, and two Strings are most often not the same object reference. (Technically, they can be the same object reference, but that's not something you need to worry about now) To be safe, use .equals to compare Strings.

To avoid a possible NullPointerException in other situations, you can also use:

while (!"Y".equals(loopChoice) && !"N".equals(loopChoice)) {
Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
1

You cannot use loopChoice != "Y", since "Y" is a String. Either use:

  • loopChoice != 'Y', or
  • "Y".equals(loopChoice)

Alternatively, use "Y".equalsIgnoreCase(loopChoice).

Case switching is also not possible for Strings if you use Java 1.6 or earlier. Be careful.

eivamu
  • 3,025
  • 1
  • 14
  • 20
  • I'm currently on Java 1.7 u51, but thanks for the reminder and for clarifying != can be used for char. – k_rollo Feb 09 '14 at 14:46
  • I have also replaced the switch with if-else-if, since the while-loopChoice check catches what the switch-default does anyway. :) – k_rollo Feb 09 '14 at 16:28
  • 1
    That's probably a good idea. Btw., the reason I write "Y".equals(loopChoice) is good just practice to avoid NullPointerException. Consider the scenario where loopChoice is null. Trying to run a method on a null object will result in NPE, whereas "Y".equals() will always work, even if loopChoice is null. – eivamu Feb 09 '14 at 20:17
  • Thank you for this explanation. I will get into the habit of "CONSTANT".equals(VARIABLE) to watch out for NPEs. :) – k_rollo Feb 10 '14 at 02:50
1

You need to know that OR Operation will return true if one of the two condition is true , so logically if you Enter Y , so you ask if the input is not equal Y so the answer is false then you will go to the next part in your condition if the input not equal N so the answer is True , so your finally result will be (True || False = True ) and then you will entered to while loop again

so the true condition is (the input not equal Y && not equal N)

Alya'a Gamal
  • 5,624
  • 19
  • 34
1

You have fallen into the common early gap between checking equality of objects versus the values of objects. (You can see a quick list of string comparison information [here] (http://docs.oracle.com/javase/tutorial/java/data/comparestrings.html)

What you wrote asks whether the object loopChoice is the same object as the string constant "Y" or the string constant "N" which will always return false. You want to ask whether the value of object loopChoice is the same as the value of string constant "Y".

You could rewrite your code as follows:

System.out.print("\nDo you want to continue (Y/N)? ");
// get value of next line, and trim whitespace in case use hit the spacebar
loopChoice = scn.nextLine().trim();


while (!("Y".equalsIgnoreCase(loopChoice) || "N".equalsIgnoreCase(loopChoice)) {
    System.out.print("\nPlease try again (Y/N)? ");
    loopChoice = scn.nextLine().toUpperCase();
}

Note, I like to put the constant value first for clarity. The general form for determining whether the value of two strings is the same is String1.equalsIgnoreCase(String2).

ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
  • What exactly is the advantage of `"Y".equals(loopChoice)` over `loopChoice.equals("Y")`? Which is considered good practice? – k_rollo Feb 09 '14 at 17:53
  • 1
    No computational difference, I just find that placing the "checked for " condition first helps mentally match the purpose of the boolean fragment. – ErstwhileIII Feb 10 '14 at 02:11