扫描仪的hasNext方法如何"not advance past any input"?



java.util.ScannerhasNexthasNextXxx方法中,它读取:

如果此扫描程序的输入中有另一个令牌,则返回true。此方法可能在等待扫描输入时发生阻塞扫描仪不会前进超过任何输入

扫描程序明明必须检查输入中是否存在下一个令牌(如ReadableInputStream(,但它怎么能不通过输入流?

在输入流中前进。从ScannerScanner用户的角度来看,它不会超过下一个输入。因此,可以说这篇文件的措辞很糟糕。

这可以通过在流中只放置一个令牌,然后为该令牌调用hasNext来轻松测试。在这种情况下,您会发现在调用hasNext之后流已经耗尽。

换句话说,Scanner在内部缓冲被偷看的字符,包括任何分隔符字符。随后的调用将从缓冲的字符开始。CCD_ 11不依赖于底层流提供的任何缓冲。

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

示例代码:

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的其他文档问题,例如在Scanner类本身的文档中,它写道:

next()hasNext()方法及其配套方法(如nextInt()hasNextInt()(首先跳过任何与分隔符模式匹配的输入,然后尝试返回下一个标记

显然最后一部分对于hasNext()是不正确的。这看起来像是hasNext被塞进了一个现有的句子中。

;通过输入"前进";在这里被融合。

第一个概念是从InputStream读取更多的字节,当然扫描器必须这样做才能测试它是否有下一个令牌。扫描程序通过缓冲从InputStream读取的新字节来实现这一点,以便以后在必要时可以从扫描程序读取这些字节。我们可以称之为";前进通过输入流";。

第二个概念是推进要从缓冲区中消耗的下一个字节的位置。当您调用像next这样消耗令牌的方法,以标记这些字节已经"被"时,就会发生这种情况;使用";并且不应该再被阅读;调用CCD_ 21使缓冲器中的位置前进。我们可以称之为";通过扫描器缓冲器中的输入前进";。

文件的声明";扫描仪不前进超过任何输入"0"是第二个概念;调用hasNext不会通过Scanner的缓冲区,它只是将输入流中的更多字节读取到缓冲区中。为了验证这一点,您可以尝试创建一个输入流,调用hasNext,然后使用nextInLine:读取下一个字符(而不是下一个令牌(

> 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]超过任何输入">在这个意义上。

最新更新