为什么是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? 假,没有空白了。