扫描程序的hasNext方法如何“不超前任何输入”?

时间:2019-11-14 17:23:38

标签: java java.util.scanner inputstream system.in

hasNext的{​​{1}}和hasNextXxx方法中,其内容为:

  

如果此扫描仪的输入中包含另一个令牌,则返回true。等待输入扫描时,此方法可能会阻塞。 扫描仪不会越过任何输入。

当扫描程序明显必须检查输入中是否存在下一个令牌(如java.util.ScannerReadable时,扫描器如何不能前进通过输入流?

2 个答案:

答案 0 :(得分:3)

确实在输入流中前进。从InputStreamScanner用户的角度来看,它只是没有越过下一个输入。因此,可以说这段文档措辞不佳。

只需在流中放入单个令牌,然后为该令牌调用Scanner,就可以轻松测试。在这种情况下,您将发现在调用hasNext之后流已耗尽。

换句话说,hasNext在内部缓冲偷看的字符,包括任何定界符。随后的呼叫将从缓冲的字符开始。 Scanner不依赖基础流提供的任何缓冲。

该文本至少在Java 12之前存在。

示例代码:

Scanner

它还包含Reader stringReader = new StringReader("Single line"); Scanner firstScanner = new Scanner(stringReader); // prints out true because there is a first line System.out.println(firstScanner.hasNextLine()); Scanner secondScanner = new Scanner(stringReader); // prints out false because the scanner has advanced the reader // ... through the character stream generated from the string System.out.println(secondScanner.hasNextLine()); // prints out true because the first scanner is buffering the input System.out.println(firstScanner.hasNextLine()); 的其他文档问题,例如在hasNext类本身的文档中显示为:

  

Scannernext()方法及其伴随方法(例如hasNext()nextInt())首先跳过任何与定界符模式匹配的输入,尝试返回下一个令牌

显然,hasNextInt()的最后一部分不正确。看来hasNext()已被塞入现有句子中。

答案 1 :(得分:1)

这里有两个“通过输入推进”的概念。

第一个概念是从InputStream读取更多字节,扫描程序当然必须执行此操作才能测试它是否具有下一个令牌。扫描程序通过缓冲从InputStream读取的新字节来完成此操作,以便以后可以在必要时从扫描程序读取这些字节。我们可以称其为“在输入流中前进”。

第二个概念是推进要从缓冲区使用的下一个字节的位置。当您调用next之类的使用令牌的方法来标记这些字节已“使用”并且不应再次读取时,会发生这种情况。调用next会使缓冲区中的位置前进。我们可以称其为“通过扫描器缓冲区中的输入前进”。

第二个概念是文档声明“扫描程​​序不会超出任何输入范围” ;调用hasNext不会通过扫描程序的缓冲区,它只是从输入流中将更多字节读入缓冲区。为了验证这一点,您可以尝试创建输入流,调用hasNext,然后使用findInLine读取下一个字符(而不是下一个标记):

> InputStream is = new ByteArrayInputStream("hello world".getBytes());
> Scanner sc = new Scanner(is);
> sc.next()
"hello" (String)
> sc.hasNext()
true (boolean)
> sc.nextInLine(".")
" " (String)

因此,调用hasNext不仅不会消耗下一个标记,而且也不会消耗下一个标记之前的定界符。在这种情况下,扫描程序没有“提前[d]超过任何输入”