Why is hasNext() False, but hasNextLine() is True?
Solution 1:
You have a single extra newline at the end of your file.
-
hasNextLine()
checks to see if there is anotherlinePattern
in the buffer. -
hasNext()
checks to see if there is a parseable token in the buffer, as separated by the scanner's delimiter.
Since the scanner's delimiter is whitespace, and the linePattern
is also white space, it is possible for there to be a linePattern
in the buffer but no parseable tokens.
Typically, the most common way to deal with this issue by always calling nextLine()
after parsing all the tokens (e.g. numbers) in each line of your text. You need to do this when using Scanner
when reading a user's input too from System.in
. To advance the scanner past this whitespace delimiter, you must use scanner.nextLine()
to clear the line delimiter. See: Using scanner.nextLine()
Appendix:
LinePattern
is defined to be a Pattern
that matches this:
private static final String LINE_SEPARATOR_PATTERN =
"\r\n|[\n\r\u2028\u2029\u0085]";
private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";
The default token delimiter is this Pattern
:
private static Pattern WHITESPACE_PATTERN = Pattern.compile(
"\\p{javaWhitespace}+");
Solution 2:
The reason is that hasNext()
checks if there are any more non-whitespace characters available. hasNextLine()
checks to see if there is another line of text available. Your text file probably has a newline at the end of it so it has another line but no more characters that are not whitespace.
Many text editors automatically add a newline to the end of a file if there isn't one already.
In other words, your input file is not this (the numbers are line numbers):
1. a 3 9
2. b 3 6
3. c 3 3
4. d 2 8
5. e 2 5
It is actually this:
1. a 3 9
2. b 3 6
3. c 3 3
4. d 2 8
5. e 2 5
6.
Solution 3:
Short answer
You have an empty line at the end of the file.
Reason for the empty line
If you take your content and save it for example into a txt file, some editors will add an empty new line to your file.
The editors behave this way, because this is part of the POSIX standard:
3.206 Line
A sequence of zero or more non- characters plus a terminating character.
This topic has been discussed in this thread.
Java Scanner documentation
Here is the documentation from the Java 8 Scanner class.
hasNext()
Returns true if this scanner has another token in its input.
hasNextLine()
Returns true if there is another line in the input of this scanner.
Reason for the Java code behavior
Because of the above described facts, hasNextLine()
will return true
, but hasNext()
cannot find anything, which it can recognize as Token
and returns therefore false
.
For additional infos see durron597 post.
Solution 4:
You are consuming the value of next()
, but asking for hasNext()
and hasNextLine()
. next()
, per default, returns everything to the next whitespace()
. So you are iterating through all whitespace seperated strings, and after each of them you are asking about the nextLine()
.
i 1 1
-> hasNextLine()
? True. hasNext()
? Also true.
1 1
-> hasNextLine()
? True. hasNext()
? Also true (still a whitespace left)
1
-> hasNextLine()
? True (Line Seperator, probably). haxNext? False, no whitespace anymore.