0

Novice here, please take it easy on me...

What is the Java/OOP way to cleanup the input validation logic I have below? The check to ensure an int has been entered is executed multiple times throughout the main method. It feels dirty duplicating input validation lines multiple times. Notice the question changes for each input.

I assume one solution is to pass keyInput and the question (a String) to a method that completes the validation and returns keyInput.nextInt when the input is good.

What would a non-novice do?

Thank you.

public static void main(String[] args) {
        
        Scanner keyInput = new Scanner(System.in);
        int level = 0;
        boolean badInput = true;
        int answer = 0;
                
        while (badInput) {
            
            System.out.print("Enter a level between 1 and 4: ");
            
            if (!keyInput.hasNextInt()) {
            
                System.out.println("*** Input is not an integer! ***\n");
                keyInput.next();
                continue;
            
            } 
            
            level = keyInput.nextInt();
    
            if (level < 1 || level > 5) {
                
                System.out.println("*** Number is not between 1 and 4! ***\n");
                continue;
                
            }
            
            badInput = false;
            
        }
                
        MathChallenge game = new MathChallenge(level);

        badInput = true;
        
        while (badInput) {
            
            System.out.print("Enter the sum of " + game.getArray() + ": ");
            if (!keyInput.hasNextInt()) {
            
                System.out.println("*** Input is not an integer! ***\n");
                keyInput.next();
                continue;
            
            }
            ...
1
  • Scanner has quirks and makes it difficult to write code that works in all cases. I personally would never use it. Instead I'd read entire lines and then parse out what I needed. Commented Jan 13, 2021 at 20:59

1 Answer 1

1

Make a method that contains the repeated code and pass any variable pieces as arguments to that method.

For example:

public int getNumber(Scanner keyInput, String prompt, int min, int max) {
    while (true) {
        System.out.print(prompt);
 
        if (!keyInput.hasNextInt()) {
            System.out.println("*** Input is not an integer! ***\n");
            keyInput.next();
            continue;
        } 
            
        number = keyInput.nextInt();
        if (number < min || number > max) {
            System.out.println("*** Number is not between " + min + " and " + max + "! ***\n");
            continue;
        }
        return number;
    }
}

Then call it like this:

public static void main(String[] args) {
    Scanner keyInput = new Scanner(System.in);
    int level = getNumber(keyInput, "Enter a level between 1 and 4:", 1, 4);
    MathChallenge game = new MathChallenge(level);
    int sum = getNumber(keyInput, ""Enter the sum of " + game.getArray() + ": ", 0, 100);
    // ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

Excuse my ignorance, but does getNumber need to be a static method?
@Kimmel You can make it static, as it doesn't use any class members. You can also leave it non-static. You can also make it private. Up to you. Depends on whether you may later want to override it or make it available elsewhere.
If I don't make getNumber static I receive compile errors due to it being called from a static context (main).
Oh, right, I missed that everything was in main. If you keep it like that, you either need to make getNumber static or first create an object to call it on: new YourClass().getNumber(...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.