我刚刚学习了Java的Scanner类,现在我想知道它如何与StringTokenizer和String.Split进行比较/竞争.我知道StringTokenizer和String.Split只适用于字符串,那么为什么我要将扫描器用于字符串呢?Scanner只是打算一站式购物吗?
他们基本上是马匹的课程.
Scanner
适用于需要解析字符串,提取不同类型数据的情况.它非常灵活,但可以说是没有为您提供最简单的API来简单地获取由特定表达式分隔的字符串数组.
String.split()
并Pattern.split()
为你提供一个简单的语法来完成后者,但这基本上就是他们所做的一切.如果要解析生成的字符串,或者根据特定令牌中途更改分隔符,它们将无法帮助您.
StringTokenizer
比String.split()
使用更加严格,而且使用起来也有点笨拙.它主要用于拉出由固定子串分隔的令牌.由于这个限制,它的速度大约是原来的两倍String.split()
.(参见我对String.split()
和的比较StringTokenizer
.)它也早于正则表达式API,它String.split()
是其中的一部分.
你会从我的时间中注意到,在典型的机器上,几毫秒内String.split()
仍可以标记数千个字符串.此外,它的优势StringTokenizer
在于它可以将输出作为字符串数组提供,这通常是您想要的.在大多数情况下,使用a Enumeration
提供的StringTokenizer
语法过于"语法上挑剔".从这个角度来看,StringTokenizer
现在有点浪费空间,你也可以使用String.split()
.
让我们从消除开始StringTokenizer
.它变老了,甚至不支持正则表达式.其文件说明:
StringTokenizer
是一个遗留类,出于兼容性原因而保留,尽管在新代码中不鼓励使用它.建议任何寻求此功能的人都使用split
方法String
或java.util.regex
包.
所以我们马上把它扔掉.这使得split()
和Scanner
.他们之间有什么区别?
首先,split()
只需返回一个数组,这样可以很容易地使用foreach循环:
for (String token : input.split("\\s+") { ... }
Scanner
更像是一个流:
while (myScanner.hasNext()) { String token = myScanner.next(); ... }
要么
while (myScanner.hasNextDouble()) { double token = myScanner.nextDouble(); ... }
(它有一个相当大的API,所以不要认为它总是局限于这么简单的事情.)
当您在开始解析之前没有(或无法获取)所有输入时,此流式接口可用于解析简单文本文件或控制台输入.
就个人而言,我唯一能记住使用的Scanner
是学校项目,当我不得不从命令行获取用户输入时.它使这种操作变得容易.但是,如果我有一个String
我想分开的东西,那几乎是不费吹灰之力的split()
.
StringTokenizer一直在那里.它是最快的,但类似枚举的习语可能看起来不像其他的那样优雅.
分裂在JDK 1.4上出现.比tokenizer慢但更容易使用,因为它可以从String类调用.
Scanner来自JDK 1.5.它是最灵活的,填补了Java API的长期缺口,以支持相当于着名的Cs scanf函数系列.
拆分很慢,但不像Scanner那么慢.StringTokenizer比split更快.然而,我发现通过交换一些灵活性,我可以获得双倍的速度,以获得速度提升,我在JFastParser上做了https://github.com/hughperkins/jfastparser
测试包含一百万个双打的字符串:
Scanner: 10642 ms Split: 715 ms StringTokenizer: 544ms JFastParser: 290ms
如果您想要标记化String对象,请使用String的split方法而不是StringTokenizer.如果您正在从程序外部的源(例如文件或用户)解析文本数据,那么Scanner就会派上用场.