Java 实例 – 字符串分隔(StringTokenizer)
在 Java 编程中,处理字符串是一项非常常见的任务。尤其是在读取配置文件、解析日志内容、处理用户输入或从数据库提取字段时,我们经常需要将一个长字符串按特定规则拆分成多个部分。这时,StringTokenizer 就是一个非常实用的工具类,它专门用于将字符串按分隔符切分成一个个“词”(token),非常适合初学者快速上手。
想象一下,你有一段用逗号分隔的用户信息:“张三,25,男,北京”。你想分别提取姓名、年龄、性别和城市。手动用 indexOf 和 substring 一个个找,不仅繁琐,还容易出错。而 StringTokenizer 就像是一个自动分拣机,你只要告诉它“用逗号切”,它就能帮你把每个字段准确地分出来。
什么是 StringTokenizer?
StringTokenizer 是 Java 标准库中 java.util 包下的一个类,它的主要作用是将字符串按照指定的分隔符进行分割。它不支持正则表达式,但胜在简单、高效,特别适合处理结构清晰、分隔符固定的字符串。
它的核心思想是:把字符串当成一个“词库”,每个分隔符之间的部分就是一个“词”。你可以像遍历数组一样,逐个获取这些“词”。
💡 小贴士:
StringTokenizer并不是在原字符串上做修改,而是通过内部状态维护当前的“位置指针”,逐个返回 token,因此它不会改变原始字符串。
基本语法与构造方法
StringTokenizer 提供了三种构造方法,最常用的是第一种:
StringTokenizer(String str, String delim)
str:要分割的原始字符串;delim:分隔符字符串,可以包含多个字符,比如",;|"表示用逗号、分号或竖线作为分隔符。
还有一个可选参数,用于控制是否保留分隔符:
StringTokenizer(String str, String delim, boolean returnDelimiters)
returnDelimiters:如果为true,则分隔符本身也会作为 token 返回。一般情况下我们设为false,只关心内容。
示例:基础使用
import java.util.StringTokenizer;
public class StringSplitExample {
public static void main(String[] args) {
// 原始字符串,用逗号分隔
String input = "Java,Python,JavaScript,Go,Rust";
// 创建 StringTokenizer 实例,以逗号为分隔符
StringTokenizer tokenizer = new StringTokenizer(input, ",");
// 输出分隔后的 token 数量
System.out.println("总共分出了 " + tokenizer.countTokens() + " 个词");
// 逐个读取每个 token
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
System.out.println("词: " + token);
}
}
}
输出结果:
总共分出了 5 个词
词: Java
词: Python
词: JavaScript
词: Go
词: Rust
✅ 注释说明:
countTokens():返回剩余可用的 token 数量,常用于判断是否还有内容可读;hasMoreTokens():判断是否还有未读的 token,是 while 循环的判断条件;nextToken():获取下一个 token,并移动内部指针,每次调用返回一个字符串。
多种分隔符的处理
在实际项目中,分隔符往往不止一种。比如日志文件中可能混合使用空格、制表符、逗号等。StringTokenizer 支持同时指定多个分隔符。
示例:使用多种分隔符
import java.util.StringTokenizer;
public class MultiDelimiterExample {
public static void main(String[] args) {
// 使用空格、逗号、制表符作为分隔符
String logLine = "用户ID: 1001, 姓名: 张三, 年龄: 28, 地区: 北京\t时间: 2024-05-01 10:30:00";
// 指定多个分隔符:空格、逗号、制表符
StringTokenizer tokenizer = new StringTokenizer(logLine, " ,\t");
// 逐个输出 token
System.out.println("分隔后的 token 列表:");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
System.out.println("→ " + token);
}
}
}
输出结果:
分隔后的 token 列表:
→ 用户ID:
→ 1001
→ 姓名:
→ 张三
→ 年龄:
→ 28
→ 地区:
→ 北京
→ 时间:
→ 2024-05-01
→ 10:30:00
✅ 注释说明:
StringTokenizer(logLine, " ,\t"):这里空格、逗号和制表符都作为分隔符;- 即使原始字符串中存在多个连续空格或制表符,
StringTokenizer会自动跳过,只返回有意义的 token;- 每个 token 都是独立的字符串,方便后续处理。
与 split() 方法的对比
很多初学者会问:既然 Java 有 String.split() 方法,为什么还要用 StringTokenizer?
我们来做一个对比:
| 特性 | StringTokenizer | String.split() |
|---|---|---|
| 是否支持正则表达式 | ❌ 不支持 | ✅ 支持 |
| 性能 | ⭐ 更快(适合频繁调用) | 🟡 一般 |
| 内存占用 | 🟢 更低(无中间数组) | 🔴 较高(返回数组) |
| 使用复杂度 | 🟢 简单直观 | 🟡 需要正则知识 |
| 是否可重用 | ❌ 一次性的迭代器 | ✅ 可重复使用 |
✅ 举个例子:如果你要处理一个包含百万条日志的文件,
StringTokenizer因为不需要创建数组,会更省内存,处理速度也更快。
示例:split() 的对比写法
String input = "Java,Python,JavaScript,Go,Rust";
String[] parts = input.split(",");
for (String part : parts) {
System.out.println("词: " + part);
}
虽然 split() 写法更现代,但 StringTokenizer 在性能敏感场景下依然有其优势。
实际应用场景:处理 CSV 数据
CSV(逗号分隔值)文件是数据交换的常见格式。我们可以用 StringTokenizer 实现一个简单的 CSV 行解析器。
示例:解析一行 CSV 数据
import java.util.StringTokenizer;
public class CSVParser {
public static void parseCSVLine(String line) {
// 使用逗号作为分隔符
StringTokenizer tokenizer = new StringTokenizer(line, ",");
int fieldIndex = 1;
while (tokenizer.hasMoreTokens()) {
String field = tokenizer.nextToken();
// 去掉首尾空格(避免读入多余空格)
field = field.trim();
System.out.printf("字段 %d: %s%n", fieldIndex++, field);
}
}
public static void main(String[] args) {
// 模拟一行 CSV 数据
String csvLine = "张三, 25, 男, 北京, 13800138000";
System.out.println("解析 CSV 行:");
parseCSVLine(csvLine);
}
}
输出结果:
解析 CSV 行:
字段 1: 张三
字段 2: 25
字段 3: 男
字段 4: 北京
字段 5: 13800138000
✅ 注释说明:
trim()用于去除字段前后的空格,避免数据污染;- 每个字段都按顺序编号,方便后续映射到对象属性;
- 可以扩展为读取整行文件,逐行解析 CSV。
注意事项与常见陷阱
-
分隔符不能是空字符串
如果你传入""作为分隔符,程序会抛出IllegalArgumentException。例如:new StringTokenizer("abc", ""); // 报错! -
不能在迭代过程中修改字符串
StringTokenizer是基于原始字符串的,如果在遍历过程中修改了原字符串,行为不可预测。 -
不支持正则表达式
不能用|、+等正则符号。如果需要,应使用split()。 -
内部状态不可逆
一旦调用nextToken(),无法回退。所以不要在循环中重复调用。
总结
Java 实例 – 字符串分隔(StringTokenizer) 是一个简单却强大的工具,尤其适合处理结构清晰、分隔符固定的字符串。它性能好、内存占用低,非常适合在日志解析、配置读取、CSV 处理等场景中使用。
虽然现代 Java 开发中 split() 更常见,但 StringTokenizer 依然在某些性能敏感的场合不可替代。掌握它,不仅让你多一种工具,也加深了对字符串处理机制的理解。
下次当你面对一个用逗号、空格或制表符分隔的字符串时,不妨先想想:是不是该用 StringTokenizer 来试试?它可能就是你代码中那个“最轻巧的分词助手”。