这只是一种好奇而不是问题...
为什么Scanner
类没有nextChar()
方法?考虑到它有next
,nextInt
,nextLine
等方法,它似乎应该有这个方法。
我知道你可以简单地执行以下操作:
userChar = in.next().charAt(0);
System.out.println( userChar );
但是为什么不添加一个nextChar()
方法呢?
这只是一种好奇而不是问题...
为什么Scanner
类没有nextChar()
方法?考虑到它有next
,nextInt
,nextLine
等方法,它似乎应该有这个方法。
我知道你可以简单地执行以下操作:
userChar = in.next().charAt(0);
System.out.println( userChar );
但是为什么不添加一个nextChar()
方法呢?
Scanner
将根据前面的Scanner
API 调用预读(和缓冲)字符。 - Stephen CScanner
不适用于读取单个字符。您需要将Scanner
附加到InputStream
(或其他内容)上,并由其解析输入。它还可以去除不需要的字符。因此,您可以轻松读取数字、行等内容。如果您只需要从输入中获取字符,请使用InputStreamReader等工具。nextChar
的意图在扫描模型中并不适合很好地解决问题。
如果 nextChar()
表现得像 Reader
上的 read()
一样,只需从扫描器返回下一个未使用字符,则它与其他 next<Type>
方法的行为不一致。这些方法在尝试解析值之前跳过分隔符字符。
如果 nextChar()
表现得像 nextInt
,则:
跳过分隔符会对某些人来说是“意外”的;
存在是否应该接受单个“原始”字符、代表 char
的数字序列或甚至支持转义等问题。1
Scanner类基于String的next(Pattern)
方法实现逻辑。其他API方法,如nextDouble()
或nextFloat()
,需要在其中提供模式。
然后description says类说:
一个简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。
扫描仪使用定界符模式将其输入拆分为标记,默认情况下匹配空格。然后,可以使用各种next方法将结果标记转换为不同类型的值。
从描述中可以看出,有人忘记了char,因为它肯定是一种原始类型。
但是该类的概念是查找模式,而char没有模式,只是下一个字符。我认为这种逻辑导致没有实现nextChar。
如果您需要逐个字符读取文件,则可以使用更有效的类。
char
占用16字节,某些编码将使用一个字节来表示一个字符,而另一种编码则会使用两个或更多字节。当Java最初设计时,他们假设任何Unicode字符都适合2个字节,而现在Unicode字符可以需要多达4个字节(UTF-32)。Scanner
没有办法用单个char
表示UTF-32代码点。Scanner
指定编码,如果未提供,则将使用平台字符集。但是,这仍然无法处理3或4字节的Unicode字符的问题,因为它们无法表示为单个char
基元(因为char
仅为16字节)。因此,您最终会得到不一致的结果。Scanner
无法检索字符,因为它无法确定编码方式,那么它如何实现_任何_扫描方法呢?毕竟,这些方法必须查看字符,不是吗? - ajbString
类型的方法?问题在于,如果你有一个4字节的Unicode字符,如何用 char
来表示它?如果是 String
,它可以在内部表示为一个带有两个 char
的 char
数组。但如果你要处理3或4字节的Unicode字符,就无法从 nextChar
中获得有意义的响应了。 - Vivin PaliathReader
负责处理编码。请查看 http://docs.oracle.com/javase/1.5.0/docs/api/index.html?java/io/InputStream.html。 - Marc Hauptmannchar[]
内部组成的。如果您正在读取UTF-32字符,那么nextChar
应该返回什么?如果它被编码为UTF-32
,则String
可以计算出每个字符需要4个字节(因为您可以将编码指定为String
)。 - Vivin PaliathScanner
内部使用一个CharBuffer
,它在内部使用一个char[]
数组。这正是我的观点:在Java中,你不能用单个char
表示UTF-32,这可能就是为什么Scanner
没有nextChar
的原因。Readable
将字节读入一个可以容纳多个char
的CharBuffer
中,因此UTF-32代码点不是问题。nextChar
的语义取决于编码。 - Vivin Paliath
next(".")
。 - Joachim Sauernext(".")
似乎会首先跳过分隔符(默认情况下是空格)。也许这就是所期望的。如果不是,您需要使用sc.delimiter()
来保存当前的分隔符模式,使用sc.useDelimiter(??)
将其设置为不匹配任何内容的模式(也许是一个空模式,但我还没有测试过);然后使用next(".")
;最后使用sc.useDelimiter
来恢复先前的分隔符。 - ajb