我们都知道,分割字符串要使用 String 的 split() 方法,split 方法虽然深入人心,使用也简单,但效率太低!

其实在 JDK 中,还有一个性能很强的纯字符串分割工具类:StringTokenizer

这个类在 JDK 1.0 中就推出来了,但在实际工作却发现很少有人使用,网上有人说不建议使用了,甚至还有人说已经废弃了,真的是这样吗?

StringTokenizer 被废弃了吗?

栈长翻阅了一些资料,原来在 Oracle JDK 官方文档中已经有了描述,这是最新的 Oracle JDK 15 的官方文档关于 StringTokenizer 的说明:

StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

参考:https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/StringTokenizer.html

StringTokenizer 原来是一个遗留类,并未被废弃,只是出于兼容性原因而被保留,在新代码中已经不鼓励使用它了,建议使用 String 的 split 方法或 java.util.regex 包代替。

再来看 StringTokenizer 类的源码:

可以看到 StringTokenizer 类并未标识 @Deprecated,说明在后续的版本中也还可以继续使用,官方还会继续保留,并不会进行删除。

就像 JDK 集合中的 Vector 和 Hashtable 类一样,虽然它们略显笨重,但并不说明它们没有用了,另外,它们也不存在致命缺陷,所以一直保留到现在并未废除掉。

StringTokenizer 没人用了吗?

答案:非也!

栈长在最新的 Spring 5.x 框架 StringUtils 工具类中就发现了 StringTokenizer 的使用身影:

org.springframework.util.StringUtils#tokenizeToStringArray

另外,栈长还看到了一篇《Faster Input for Java》的文章,其中就介绍了他们是使用 StringTokenizer 来分割字符串的,其效率是 string.split() 的 4 倍

We split the input line into string tokens, since one line may contain multiple values. To split the input, StringTokenizer is 4X faster than string.split().

参考:https://www.cpe.ku.ac.th/~jim/java-io.html

所以,即使 JDK 不鼓励使用它了,但它并未被废除,并且性能还这么强,在一些对性能比较敏感的系统中,或者对性能比较有要求的编程竞赛中,StringTokenizer 就能发挥重要作用。

所以,大胆用吧,StringTokenizer 还是可以用的,用的好还能出奇效!另外,往期 Java 技术系列文章我也已经整理好了,关注公众号Java技术栈,在后台回复:java,可以获取阅读,非常齐全。

StringTokenizer vs split

说了这么多,相信大部分人都只用过 split,而没用过 StringTokenizer,那么栈长今天就来对比下这两个字符串分割法的性能及利弊。

测试代码如下:

import java.util.Random;
import java.util.StringTokenizer;/*** @author: 栈长* @from: 公众号Java技术栈*/
public class SplitTest {private static final int MAX_LOOP = 10000;/*** @author: 栈长* @from: 公众号Java技术栈*/public static void main(String[] args) {StringBuilder sb = new StringBuilder();System.out.println(sb.toString());for (int i = 0; i < 1000; i++) {sb.append(new Random().nextInt()).append(" ");}split(sb.toString());stringTokenizer(sb.toString());}/*** @author: 栈长* @from: 公众号Java技术栈*/private static void split(String str) {long start = System.currentTimeMillis();for (int i = 0; i < MAX_LOOP; i++) {String[] arr = str.split(" ");StringBuilder sb = new StringBuilder();for (int j = 0; j < arr.length; j++) {sb.append(arr[j]);}}System.out.printf("split 耗时 %s ms\n", System.currentTimeMillis() - start);}/*** @author: 栈长* @from: 公众号Java技术栈*/private static void stringTokenizer(String str) {long start = System.currentTimeMillis();for (int i = 0; i < MAX_LOOP; i++) {StringTokenizer stringTokenizer = new StringTokenizer(str, " ");StringBuilder sb = new StringBuilder();while (stringTokenizer.hasMoreTokens()) {sb.append(stringTokenizer.nextToken());}}System.out.printf("StringTokenizer 耗时 %s ms", System.currentTimeMillis() - start);}}

在我本机测试结果如下:

测试次数 split StringTokenizer
1 1ms 1ms
10 7ms 3ms
100 30ms 16ms
1000 129ms 51ms
10000 570ms 486ms
100000 3816ms 3130ms

从测试数据看,虽然 StringTokenizer 有一点性能优势,但并不太明显,我并没有测试出有 4 倍的性能差距,可能和测试数据、测试方法、以及测试的 JDK 版本有关系。

然后,我再把 split 测试方法中的 " " 改成 "\\s"

测试次数 split StringTokenizer
1 6ms 1ms
10 25ms 4ms
100 90ms 20ms
1000 240ms 59ms
10000 835ms 481ms
100000 5616ms 3362ms

把 split 方法改成正则表达式再测试,这下差距就明显了。

我们都知道解析正则表达式会比较慢一点,这很正常,但 StringTokenizer 并不支持传入正则表达式,只能使用字符串作为分隔符,所以这测试结果就没多大意义了,这就是症结了。。

总结

虽然 JDK 不鼓励使用 StringTokenizer 了,但并不说明它不能用了,相反,如果你的系统对性能有非常严格的要求,又不是很复杂的字符串分割,好好使用它反而可以带来高效。

但话又说回来,一般的应用程序用 split 也就够了,因为它够简单、又支持正则表达式,在一般的应用中也不会存在像文中测试的大批量的字符串循环分割,另外,StringTokenizer 在单次分割的性能上也没有性能优势。

最后,关于字符串的分割方法,我们除了字符串本身的 split 方法,我们还要知道 StringTokenizer 这个类,多知道点不是坏事。另外,在 Spring、Apache Commons 工具类中也都有封装好的 StringTokenizer 工具类,有兴趣的可以直接拿去用。

好了,今天的分享就到这里了,后面栈长我会更新更多好玩的 Java 技术文章,关注公众号Java技术栈第一时间推送,不要走开哦。

本节教程所有实战源码已上传到这个仓库:

https://github.com/javastacks/javastack

最后,觉得我的文章对你用收获的话,动动小手,给个在看、转发,原创不易,栈长需要你的鼓励。

版权申明:本文系公众号 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重大家的劳动成果和知识产权,抄袭必究。

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2021最新版)

2.终于靠开源项目弄到 IntelliJ IDEA 激活码了,真香!

3.阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式发布,全新颠覆性版本!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

你只会用 split?试试 StringTokenizer,性能可以快 4 倍!!相关推荐

  1. 关于split与StringTokenizer的理解

    关于split与StringTokenizer的理解 一.split    依据匹配给定的正則表達式来拆分此字符串.此方法返回的数组包括此字符串的子字符串,每一个子字符串都由还有一个匹配给定表达式的子 ...

  2. php explode 效率,PHP字符分割explode,split,preg_split性能比较

    PHP字符分割explode,split,preg_split性能比较 三个函数都是用来对字符串进行分割,下面分几个实验来比较之间的性能. 1. explode与split比较 都用字符进行分割,执行 ...

  3. c#随机数生成编号_忘掉 Snowflake,感受一下性能高出587倍的全局唯一ID生成算法...

    今天我们来拆解 Snowflake 算法,同时领略百度.美团.腾讯等大厂在全局唯一 ID 服务方面做的设计,接着根据具体需求设计一款全新的全局唯一 ID 生成算法.这还不够,我们会讨论到全局唯一 ID ...

  4. 微信用户全局唯一标识_忘掉 Snowflake,感受一下性能高出587倍的全局唯一ID生成算法...

    今天我们来拆解 Snowflake 算法,同时领略百度.美团.腾讯等大厂在全局唯一 ID 服务方面做的设计,接着根据具体需求设计一款全新的全局唯一 ID 生成算法.这还不够,我们会讨论到全局唯一 ID ...

  5. snowflake做主键 自增_忘掉 Snowflake,感受一下性能高出 587 倍的全局唯一 ID 生成算法...

    今天我们来拆解 Snowflake 算法,同时领略百度.美团.腾讯等大厂在全局唯一 ID 服务方面做的设计,接着根据具体需求设计一款全新的全局唯一 ID 生成算法.这还不够,我们会讨论到全局唯一 ID ...

  6. mysql序列号生成_忘掉 Snowflake,感受一下性能高出587倍的全局唯一ID生成算法

    今天我们来拆解 Snowflake 算法,同时领略百度.美团.腾讯等大厂在全局唯一 ID 服务方面做的设计,接着根据具体需求设计一款全新的全局唯一 ID 生成算法.这还不够,我们会讨论到全局唯一 ID ...

  7. 忘掉 Snowflake,感受一下性能高出587倍的全局唯一ID生成算法

    今天我们来拆解 Snowflake 算法,同时领略百度.美团.腾讯等大厂在全局唯一 ID 服务方面做的设计,接着根据具体需求设计一款全新的全局唯一 ID 生成算法.这还不够,我们会讨论到全局唯一 ID ...

  8. 英伟达颠覆CPU!Arm架构专为AI而生,性能超x86十倍

    30系显卡买不到?英伟达老黄刚刚又发布一款"空气CPU". 不过就算你抢不到也没关系,因为这款CPU专门为服务器设计,到2023年才能发布. 刚刚,在英伟达举办的GPU技术大会上( ...

  9. 英伟达发布“空气CPU”,Arm架构专为AI而生,性能超x86十倍,与自家GPU更搭

    梦晨 晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 30系显卡买不到?英伟达老黄刚刚又发布一款"空气CPU". 不过就算你抢不到也没关系,因为这款CPU专门为服务器 ...

最新文章

  1. [精选代码笔记]Anagram, group-anagrams, two sum
  2. 【2017年第3期】开放政府环境下医药公司与医生之间的价值转移
  3. C#LeetCode刷题之#622-设计循环队列​​​​​​​(Design Circular Queue)
  4. javaweb(10) cookiesession
  5. Matlab之数据的输入与输出
  6. 在linux系统上启动oracle的服务
  7. Microsoft SQL Server 2005简体中文开发版下载说明
  8. M1 mac 安装打印机驱动程序
  9. linux系统ping地址端口,linux ping 带端口
  10. 恩格列净治疗心衰获得FDA快速通道资格
  11. Android 屏蔽Power键 Home键
  12. 纳什均衡C++简单实现
  13. 英语情景对话计算机专业,英语情景对话 寒假生活 5人
  14. 西瓜书——多元线性回归(知识点:多元实值函数凹凸性的证明)
  15. Eclipse中使用search功能,搜索内容无法多窗口打开
  16. 如何在控制台创建文件夹
  17. 5G工业网关下工业自动化设备远程监控系统
  18. 【WIN10】如何关闭右下角输入法的“拼”字
  19. STM32C8T6的FreeRTOS移植
  20. 软件构造复习——面向对象编程(PPT7)

热门文章

  1. plsql odbc导入器dsn没有下拉选项
  2. CSS3选择器(选择符)
  3. 技术博客那些事儿-如何写好博客
  4. 有12个小球,外形相同,其中一个小球的质量与其他11个不同
  5. matlab四元一次非线性方程求解,[转载]MATLAB求解非线性方程(转)
  6. display , visibility
  7. 微信小程序之组件 —— 微信小程序教程系列(19)
  8. linux查看进程所在运行目录
  9. win10查看计算机系统版本,Win10版本怎么看?Win10系统版本查看方法
  10. session-based recommendation的两个模型对比NARM, STAMP