Scanner vs. StringTokenizer vs. String.Split

问题

我刚刚学习了Java的Scanner类,现在我想知道它如何与StringTokenizer和String.Split进行比较/竞争。我知道StringTokenizer和String.Split只适用于字符串,那么为什么我要将扫描器用于字符串呢? Scanner只是打算一站式购物吗?


#1 热门回答(220 赞)

他们基本上是马匹的课程。

  • 扫描程序适用于需要解析字符串,提取不同类型数据的情况。它非常灵活,但可以说是没有为你提供最简单的API来简单地获取由特定表达式分隔的字符串数组。
  • String.split()和Pattern.split()为你提供了一个简单的语法来实现后者,但这基本上就是他们所做的一切。如果要解析生成的字符串,或者根据特定标记中途更改分隔符,它们将无法帮助你。
  • StringTokenizer比String.split()更具限制性,并且使用起来也有些小问题。它主要用于拉出由固定子串分隔的标记。由于这个限制,它的速度大约是String.split()的两倍。 (请参阅我对String.split()和StringTokenizer的比较。)它也早于正则表达式API,其中String.split()是其中的一部分。

你会从我的时间中注意到,在一台典型的机器上,String.split()仍可以在几毫秒内对千个字符串进行标记。此外,它具有超过StringTokenizer的优势,它可以将输出作为字符串数组,这通常是你想要的。使用由StringTokenizer提供的aEnumeration,在大多数情况下过于"语法上挑剔"。从这个角度来看,StringTokenizer现在有点浪费空间,你也可以使用4224394826。


#2 热门回答(54 赞)

让我们从消除StringTokenizer开始。它变老了,甚至不支持正则表达式。其文件说明:

StringTokenizer是一个遗留类,出于兼容性原因而保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人都使用String的split方法或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();
    ...
}

(它有一个相当的large API,所以不要认为它总是局限于这么简单的事情。)

当你在开始解析之前没有(或无法获取)所有输入时,此流式接口可用于解析简单文本文件或控制台输入。

就个人而言,当我不得不从命令行获取用户输入时,我唯一能记住用于学校项目的Scanner。它使这种操作变得容易。但是,如果我有一个String,我想分开,那么与split()一起使用几乎是不费吹灰之力的。


#3 热门回答(9 赞)

StringTokenizer总是在那里。它是最快的,但类似枚举的习语可能看起来不像其他的那样优雅。

分裂在JDK 1.4上出现。比tokenizer慢但更容易使用,因为它可以从String类调用。

扫描仪开始使用JDK 1.5。它是最灵活的,填补了Java API的长期缺口,以支持相当于着名的Cs scanf函数系列。