为什么是hasNext()假,但hasNextLine()是真的?
题
对于扫描器对象, hasNextLine()
方法返回true,而hasNext()
方法返回false时如何呢?
注意:基于input文件, hasNext()
方法正在按照预期返回结果; hasNextLine()
似乎没有返回正确的结果。
码
下面是我正在运行的代码,创build下面的结果:
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(); }
input文件
以下是我传递给此扫描器的文件的实际内容:
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
结果
以下是我在运行代码时在控制台中打印的内容的结尾,包括我无法理解的部分:
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()
检查缓冲区中是否存在另一个linePattern
。 -
hasNext()
检查缓冲区中是否存在可分析的令牌,由扫描器的分隔符分隔。
由于扫描器的分隔符是空格,并且linePattern
也是空格,所以缓冲区中可能有一个linePattern
,但是没有可parsing的标记。
通常,parsing这个问题的最常见的方法是,在parsing文本的每一行中的所有记号(例如数字)后总是调用nextLine()
。 在从System.in
读取用户input时也需要使用Scanner
。 要使扫描器超过此空格分隔符,必须使用scanner.nextLine()
来清除行分隔符。 请参阅: 使用scanner.nextLine()
附录:
LinePattern
被定义为一个匹配的Pattern
:
private static final String LINE_SEPARATOR_PATTERN = "\r\n|[\n\r\u2028\u2029\u0085]"; private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";
默认的令牌分隔符是这个Pattern
:
private static Pattern WHITESPACE_PATTERN = Pattern.compile( "\\p{javaWhitespace}+");
原因是hasNext()
检查是否有更多的非空白字符可用。 hasNextLine()
检查是否有另一行文本可用。 你的文本文件可能在它的最后有一个换行符,所以它有另一行,但没有更多的字符不是空白。
如果没有文本编辑器,许多文本编辑器会自动在文件末尾添加换行符。
换句话说,你的input文件不是这个(数字是行号):
1. a 3 9 2. b 3 6 3. c 3 3 4. d 2 8 5. e 2 5
其实是这样的:
1. a 3 9 2. b 3 6 3. c 3 3 4. d 2 8 5. e 2 5 6.
简短的回答
文件末尾有空行。
空行的原因
如果你把你的内容并保存到一个txt文件,一些编辑将添加一个空的新行到您的文件。
编辑的行为是这样的,因为这是POSIX标准的一部分:
3.206线
零个或多个非字符序列加上终止字符。
这个话题已经在这个线程中讨论过了。
Java扫描仪文档
这里是Java 8 Scanner类的文档。
hasNext()
如果此扫描器在其input中有另一个标记,则返回true。
hasNextLine()
如果此扫描仪的input中有另一行,则返回true。
Java代码行为的原因
由于上述事实, hasNextLine()
将返回true
,但hasNext()
找不到任何东西,它可以识别为Token
,因此返回false
。
欲了解更多信息,请参阅durron597文章。
你正在使用next()
的值,但要求hasNext()
和hasNextLine()
。 next()
,默认情况下,返回所有内容到下一个whitespace()
。 所以你正在遍历所有空白分隔的string,并且在他们每个人之后,你都在询问nextLine()
。
i 1 1
– > hasNextLine()
? 真正。 hasNext()
? 也是如此。
1 1
– > hasNextLine()
? 真正。 hasNext()
? 也是如此(仍然是一个空白)
1
– > hasNextLine()
? 真(线分隔符,可能)。 haxNext? 假,没有空白了。