You have two problems:
an extra Scanner
, and indistinguishable inputs.
In the order they appear in your code...
1. Dueling Scanners
As a general rule, you want only one Scanner
per input stream.
If the first Scanner
"reads ahead" to fill its input buffer, those bytes will vanish forever when the Scanner
gets garbage-collected.
This typically leads to a NoSuchElementException
when the next Scanner
tries to read inputs that no longer exist.
Note that this is not the same as trying to read from a closed input stream
(see "java.util.NoSuchElementException - Scanner reading user input") ---
losing inputs can happen even when the input stream is still open.
A much better strategy is to create just one Scanner
, and then pass it to each method that needs to read from it:
public static void main(final String[] args) {
final Scanner in = new Scanner(System.in); // The one and only.
ArrayList<Double> inputs = getNumbers(in);
int numberToDrop = getLowestNumber(in);
// ...
}
2. Indistinguishable Inputs
Also, you need a way to determine the end of the floating-point data and the start of the integer.
You can't do that with hasNextDouble
, because an integer input like 3
is also a perfectly good double
.
Fortunately, you have already told the user that you will only read to the end of the line, and nextLine
does exactly that.
I created a throw-away Scanner
to read double
values from the String
returned by nextLine
.
(The new Scanner parser
does not conflict with Scanner in
, because they read from different sources.)
public static ArrayList<Double> getNumbers(final Scanner in) {
System.out.println(
"Please enter five to ten numbers all on one line " +
"separated with spaces."
);
final String s = in.nextLine();
final Scanner parser = new Scanner(s);
ArrayList<Double> inputs = new ArrayList<>();
while (parser.hasNextDouble()) {
inputs.add(parser.nextDouble());
}
parser.close();
return inputs;
}
I checked the input with hasNextInt
and returned 0
if it wasn't a valid integer:
public static int getLowestNumber(final Scanner in) {
System.out.println(
"How many of the lowest values should be dropped?"
);
if (in.hasNextInt()) {
return in.nextInt();
}
return 0;
}
I think both of the scanning methods should throw exceptions if they encounter bogus inputs, rather than trying to make do like this...
The only thing worse than bogus data is a plausible result based on that bogus data.