Java 的 Scanner vs String.split() vs StringTokenizer;我应该使用哪个?

Java's Scanner vs String.split() vs StringTokenizer; which should I use?

提问人: 提问时间:4/10/2009 最后编辑:skaffman 更新时间:6/15/2015 访问量:24067

问:

我目前正在使用扫描一个文件,其中每行都有用 分隔的字符串数。我在某处读到,在性能方面,长文件可以做得更好,所以我想检查一下。split()'~'Scanner

我的问题是:我是否必须创建两个实例?也就是说,一个用于读取一行,另一个基于该行来获取分隔符的令牌?如果我必须这样做,我怀疑我是否会从使用它中获得任何好处。也许我在这里遗漏了什么?Scanner

则表达式 拆分 java.util.scanner

评论


答:

3赞 CookieOfFortune 4/10/2009 #1

我会说这是最快的,而且可能足以满足你正在做的事情。它不如它那么灵活。 已弃用,仅适用于向后兼容,因此请勿使用它。split()scannerStringTokenizer

编辑:您可以随时测试这两种实现,看看哪一个更快。我很好奇自己是否可以比.对于给定大小的 VS,拆分可能会更快,但我不能确定这一点。scannersplit()Scanner

评论

0赞 gedevan 4/10/2009
我同意 StringTokenizer 可能已被弃用,但我没有在 j2se5 和 java6 的弃用类列表中找到它。为什么?
0赞 CookieOfFortune 4/13/2009
你是对的,事实并非如此。但从 API 来看:StringTokenizer 是一个遗留类,出于兼容性原因而保留,尽管不鼓励在新代码中使用它。建议任何寻求此功能的人都改用 String 的 split 方法或 java.util.regex 包。
6赞 Jerrish Varghese 4/10/2009 #2

对于处理行,您可以使用扫描器,对于从每行获取令牌,您可以使用拆分。

Scanner scanner = new Scanner(new File(loc));
try {
    while ( scanner.hasNextLine() ){
        String[] tokens = scanner.nextLine().split("~");
        // do the processing for tokens here
    }
}
finally {
    scanner.close();
}
5赞 Alan Moore 4/10/2009 #3

您可以使用该方法让 使用 遍历每行上的标记,同时仍用于遍历行本身。useDelimiter("~")hasNext()/next()hasNextLine()/nextLine()

编辑:如果你要做一个性能比较,你应该在做split()测试时预编译正则表达式:

Pattern splitRegex = Pattern.compile("~");
while ((line = bufferedReader.readLine()) != null)
{
  String[] tokens = splitRegex.split(line);
  // etc.
}

如果使用 ,则每次都会重新编译正则表达式。(Scanner 在首次编译所有正则表达式时会自动缓存它们。如果你这样做,我不希望看到性能有太大差异。String#split(String regex)

2赞 BeeOnRope 7/13/2012 #4

你在这里实际上不需要正则表达式,因为你是在固定的字符串上拆分。Apache split 对纯字符串进行拆分。StringUtils

对于大容量拆分,其中拆分是瓶颈,而不是说文件 IO,我发现这比 .但是,我没有针对编译的正则表达式对其进行测试。String.split()

Guava 也有一个拆分器,以更 OO 的方式实现,但我发现它比 StringUtils 慢得多,用于大容量拆分。

8赞 Sreesankar 5/16/2013 #5

在单线程模型中围绕这些做了一些指标,这是我得到的结果。

~~~~~~~~~~~~~~~~~~Time Metrics~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Tokenizer  |   String.Split()   |    while+SubString  |    Scanner    |    ScannerWithCompiledPattern    ~
~   4.0 ms   |      5.1 ms        |        1.2 ms       |     0.5 ms    |                0.1 ms            ~
~   4.4 ms   |      4.8 ms        |        1.1 ms       |     0.1 ms    |                0.1 ms            ~
~   3.5 ms   |      4.7 ms        |        1.2 ms       |     0.1 ms    |                0.1 ms            ~
~   3.5 ms   |      4.7 ms        |        1.1 ms       |     0.1 ms    |                0.1 ms            ~
~   3.5 ms   |      4.7 ms        |        1.1 ms       |     0.1 ms    |                0.1 ms            ~
____________________________________________________________________________________________________________

结果是 Scanner 提供了最好的性能,现在需要在多线程模式下进行评估!我的一位前辈说 Tokenizer 会给出 CPU 峰值,而 String.split 不会。