1

How do I resolve the java.util.NoSuchElementException error? I call the scanner object 3 times, and the program will accept input the first two times. But on the third try, I immediately get the java.util.NoSuchElementException error. The name of the scanner object is stdInput.

I've tried creating a new scanner object just for the instance throwing this error, but I still get the same error, just from a different line in the code.

/**
 * reddit url:  https://www.reddit.com/r/dailyprogrammer/comments/pjbj8/easy_challenge_2/
 */

import java.util.Scanner;

public class challenge {

    public static void main(String[] args) {

        int choiceNum = 0;
        boolean continueRunningProgram = true;
        String repeatProgram = "";
        Scanner stdInput = new Scanner (System.in);

        do {

            System.out.println("Are you solving for force (1), mass (2), or acceleration (3)?");
            choiceNum = stdInput.nextInt();

            if(isValidChoiceNum(choiceNum) == false) {

                do {

                    System.out.println("The number " + choiceNum + " is an invalid choice.  Please choose again.");
                    choiceNum = stdInput.nextInt();

                } while(isValidChoiceNum(choiceNum) == false);

            }

            switch(choiceNum) {

                case 1:
                    System.out.println("The force is " + solvingForForce());
                    break;

                case 2:
                    System.out.println("The mass is " + solvingForMass());
                    break;

                case 3:
                    System.out.println("The acceleration is " + solvingForAcceleration());
                    break;
            }

            System.out.println("Would you like to solve another problem involving force, mass, and acceleration (Y/N)?");
            repeatProgram = stdInput.next();

            if(isValidChoiceChar(repeatProgram) == false) {

                do {

                    System.out.println("The letter " + repeatProgram + " is an invalid choice.  Please choose again.");
                    repeatProgram = stdInput.next();

                } while(isValidChoiceChar(repeatProgram) == false);

            }

            if(repeatProgram.compareTo("Y") == 0) {

                continueRunningProgram = true;

            } else {

                continueRunningProgram = false;

            }

        } while(continueRunningProgram == true);

        stdInput.close();

    } // end of main method

    public static boolean isValidChoiceNum(int c) {

        if(c < 1 || c > 3 ) {

            return false;

        } else {

            return true;

        }

    }

    public static boolean isValidChoiceChar(String c) {

        if(c.compareTo("Y") == 0 || c.compareTo("N") == 0) {

            return true;

        } else {

            return false;

        }

    }

    public static double solvingForForce() {

        Scanner stdInput2 = new Scanner (System.in);

        System.out.println("Please enter a value for mass.");
        double m = stdInput2.nextDouble();

        System.out.println("Please enter a value for acceleration.");
        double a = stdInput2.nextDouble();

        stdInput2.close();

        return m * a;

    }

    public static double solvingForMass() {

        Scanner stdInput2 = new Scanner (System.in);

        System.out.println("Please enter a value for force.");
        double f = stdInput2.nextDouble();

        System.out.println("Please enter a value for acceleration.");
        double a = stdInput2.nextDouble();

        stdInput2.close();

        return f / a;

    }

    public static double solvingForAcceleration() {

        Scanner stdInput2 = new Scanner (System.in);

        System.out.println("Please enter a value for force.");
        double f = stdInput2.nextDouble();

        System.out.println("Please enter a value for mass.");
        double m = stdInput2.nextDouble();

        stdInput2.close();

        return f * m;

    }

} // end of class
user207421
  • 305,947
  • 44
  • 307
  • 483

1 Answers1

1

Stop the madness of closing a Scanner linked to System.in! It will close the underlying stream (System.in), causing any other attempt to read from that Stream to throw an exception.

Yes you will get a warning, but it is safe to ignore that warning, or you can add

@SuppressWarnings("resource")
Scanner in = new Scanner(System.in);

To avoid it.

Remember, if you didn't open a resource, you shouldn't close it. Let the JVM close it when it terminates the program.


This also includes creating a Scanner(System.in) inside a try with resources block:

try(Scanner in = new Scanner(System.in)){
   //Code... 
} 

This will implicitly close the stream at the end of the block.

From the Java tutorials:

The try-with-resources statement ensures that each resource is closed at the end of the statement.


Also you have several Scanner objects reading from System.in, which is bad practice. I would pass them to your methods as a parameter:

public static double solvingForMass(Scanner in) {

    System.out.println("Please enter a value for force.");
    double f = in.nextDouble();

    System.out.println("Please enter a value for acceleration.");
    double a = in.nextDouble();

    return f / a;

}

Also just a note that if you are ever doing the structure of:

if(someBool)
   return true;
else
   return false;

It can be simplified to just

return someBool

So your isValidChoice() method can be simplified to:

public static boolean isValidChoiceChar(String c) {
     return c.compareTo("Y") == 0 || c.compareTo("N") == 0;
}

Although note you can use the equals() and equalsIgnoreCase()methods to compareString`'s

GBlodgett
  • 12,704
  • 4
  • 31
  • 45
  • Thank you so much @GBlodgett!!! Not only did you resolve my issue, but you also gave me some other useful tips too. Please feel free to provide any other suggestions you may have. I really appreciate it. – justAnotherNoob Jan 29 '19 at 13:57
  • @NeoSoulPanther The only other suggesting I have is in your `if` statements, `if(validChoice(choice) == false)` can be rewritten to `if(!validChoice(choice))` – GBlodgett Jan 29 '19 at 16:29
  • Gotcha. Thanks again for the suggestions! – justAnotherNoob Feb 01 '19 at 16:27