How is it that for a scanner object the hasNextLine()
method returns true while the hasNext()
method returns false?
Note: Based on the input file, the hasNext()
method is returning the result as expected; the hasNextLine()
does not seem to be returning the correct result.
Here's the code I'm running that's creating the results below:
public void ScannerTest(Reader fileReaderObject){
Scanner scannerObj = new Scanner(fileReaderObject);
for(int i = 1; scannerObj.hasNext(); i++){
System.out.println(i + ": " + scannerObj.next());
System.out.println("Has next line: " + scannerObj.hasNextLine());
System.out.println("Has next: " + scannerObj.hasNext());
}
System.out.println();
scannerObj.close();
}
The following is the actual content of the file that I'm passing to this scanner:
a 3 9
b 3 6
c 3 3
d 2 8
e 2 5
f 2 2
g 1 7
h 1 4
i 1 1
The following is the end of what's printed in the console when I run my code, and includes the portion I can't make sense of:
25: i
Has next line: true
Has next: true
26: 1
Has next line: true
Has next: true
27: 1
Has next line: true
Has next: false
hasNextLine()
checks to see if there is another linePattern
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}+");