你只会用 split?试试 StringTokenizer,性能可以快 4 倍
mhr18 2025-07-09 14:29 3 浏览 0 评论
我们都知道,分割字符串要使用 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/ja...
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...
所以,即使 JDK 不鼓励使用它了,但它并未被废除,并且性能还这么强,在一些对性能比较敏感的系统中,或者对性能比较有要求的编程竞赛中,StringTokenizer 就能发挥重要作用。
所以,大胆用吧,StringTokenizer 还是可以用的,用的好还能出奇效!另外,往期 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);
}
}
在我本机测试结果如下:
从测试数据看,虽然 StringTokenizer 有一点性能优势,但并不太明显,我并没有测试出有 4 倍的性能差距,可能和测试数据、测试方法、以及测试的 JDK 版本有关系。
然后,我再把 split 测试方法中的 " " 改成 "\\s":
把 split 方法改成正则表达式再测试,这下差距就明显了。
我们都知道解析正则表达式会比较慢一点,这很正常,但 StringTokenizer 并不支持传入正则表达式,只能使用字符串作为分隔符,所以这测试结果就没多大意义了,这就是症结了。。
总结
虽然 JDK 不鼓励使用 StringTokenizer 了,但并不说明它不能用了,相反,如果你的系统对性能有非常严格的要求,又不是很复杂的字符串分割,好好使用它反而可以带来高效。
但话又说回来,一般的应用程序用 split 也就够了,因为它够简单、又支持正则表达式,在一般的应用中也不会存在像文中测试的大批量的字符串循环分割,另外,StringTokenizer 在单次分割的性能上也没有性能优势。
最后,关于字符串的分割方法,我们除了字符串本身的 split 方法,我们还要知道 StringTokenizer 这个类,多知道点不是坏事。另外,在 Spring、Apache Commons 工具类中也都有封装好的 StringTokenizer 工具类,有兴趣的可以直接拿去用。
好了,今天的分享就到这里了,后面栈长我会更新更多好玩的 Java 技术文章,关注Java技术栈第一时间推送,不要走开哦。
本节教程所有实战源码已上传到这个仓库:
https://github.com/javastacks...
最后,觉得我的文章对你用收获的话,动动小手,给个在看、转发,原创不易,栈长需要你的鼓励。
版权申明:本文系 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重大家的劳动成果和知识产权,抄袭必究。
相关推荐
- mysql一 基本操作(mysql基础操作命令)
-
先讲数据库--mysql、redis、MongoDB爬虫今天的内容:mysql一基本操作注意事项:1.安装:自己安装,有问题可以问老师、可以自己找办法解决2.上课:先讲知识点再回答问题3....
- 香港DM德馬景泰藍文科集團20250702期《生命的收獲》LIN JING DE
-
香港DM德馬景泰藍文科集團20250702期《生命的收獲》DMSIXSEVEN/LINJINGDE/1973主編供圖:香港DM德馬數字甲骨文集團Hongkong-basedDMDelm...
- 01.Java发展历史(java发展简史)
-
1.Java发展历史Java由SunMicrosystems公司(现为Oracle公司)的JamesGosling及其团队在1991年开发,最初命名为"Oak",后改名为"...
- 月薪最高12000!看看这些宝山岗位有没有你心仪的~
-
招聘目录信息1猎上网络科技(上海)有限公司职位分析师职位分析师助理2上海祥腾金属材料有限公司商务车驾驶员3上海赋拓物联网技术有限公司软件测试工程师4上海集优标五高强度紧固件有限公司...
- 69岁的Java之父终于退休了,他竟然也经历过职场PUA
-
有些程序员不到35岁就要担心被优化,但有的程序员干到了69岁的高龄,才准备退休。就前几天,Java之父詹姆斯·高斯林,自个儿在领英上宣布以后要美美享受退休生活了。这一下子,就炸出了不少...
- ocm认证年薪多少?(ocm认证好考吗)
-
从业数据库方面的工程师待遇都很好,年薪30万都是比较平常的事。OCM认证的价值可以归纳成以下几点:1、可以全面掌握Oracle知识,专业知识完善;2、证书对于公司招投标有巨大作用,甚至可以不上班就拿钱...
- 自学java开发攻略,想做程序员的必备攻略?
-
背景现阶段,随着互联网的快速发展,程序员这个行业越来月吃香,不仅仅是因为科技先进,说出去很牛逼,让别人产生崇拜,主要原因是程序员行业薪资待遇好,相比国内其他行业,程序员的薪资待遇是羡慕了很多人呢!于是...
- SpringBoot WebFlux整合R2DBC实现数据库反应式编程
-
环境:Springboot2.4.12R2DBC简介SpringdataR2DBC是更大的Springdata系列的一部分,它使得实现基于R2DBC的存储库变得容易。R2DBC代表反应式关系数...
- AI编码工具未能代替码农:大模型的局限性揭秘
-
随着ChatGPT和GithubCopilot等AI编码工具的兴起,StackOverflow近日因流量减少宣布裁员近三分之一。这引发了一个争议的问题:ChatGPT这类AI编码工具,真的要颠覆整...
- 大模型无法替代码农!GPT-4解决GitHub编程问题成功率为0
-
编辑:编辑部【新智元导读】ChatGPT之类的AI编码工具来势汹汹,StackOverflow又裁员了!不过,普林斯顿和芝大竟发现,面对真实世界GitHub问题,GPT-4的解决率竟是0%。Stac...
- 机器人动作领域突破!UniVLA模型实现跨模态AI机器人动作统一
-
还记得《星际穿越》中那台能在无重力、尘暴甚至巨浪中切换形态、随时理解库珀指令的TARS多功能机器人吗?在银幕里,我们羡慕TARS能听懂人话、看懂环境、马上给出最合适的动作;而在现实世界的实验室里,“让...
- FEA-Bench:首个仓库级新功能实现基准,让大模型更懂软件开发
-
当前,大语言模型在代码生成领域已展现出惊人的能力,但能否胜任真实软件开发中的“新增功能实现”任务,仍是一个关键未解的问题。对此,微软亚洲研究院与北京大学联合发布了首个专注于仓库级新功能实现的基准测试...
- 基于Java的软件版本信息管理系统-2025计算机毕业设计
-
基于Java的软件版本信息管理系统-2025计算机毕业设计前言随着移动互联网的快速发展,APP已成为人们日常生活中不可或缺的一部分。为了高效地管理这些APP的信息,如版本更新、用户反馈、下载量统计等,...
- 马斯克在干嘛?抱着它现身推特 简介改为“推特老板”
-
马斯克收购推特的交易真是“没完没了”。据彭博社报道,当地时间26日,美国亿万富翁埃隆·马斯克抱着水槽走进了推特公司的旧金山总部,他还将自己在推特账号的公开自我介绍改为“推特老板”(ChiefTw...
- 福布斯公布7月全球十大富豪:马斯克成6月最大“输家”,身家缩水160亿美元
-
7月日,福布斯今日公布了2025年7月全球十大富豪榜,其中第二名迎来新面孔。软件巨头甲骨文(Oracle)联合创始人兼董事长拉里埃里森(LarryEllison)凭借公司股价飙升成功上位。由...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)