核心概念
String.split() 方法是一个实例方法,它根据一个正则表达式作为分隔符,将当前字符串分割成一个字符串数组。
方法签名:
public String[] split(String regex)
参数说明:
regex: 一个正则表达式,用作分割字符串的边界。特别注意,这里的参数是正则表达式,而不仅仅是普通字符。
返回值:
- 一个字符串数组,数组中的每个元素都是原字符串被分割后的子字符串。
基本用法示例
示例 1:使用普通字符作为分隔符
当分隔符是简单的字符(如 , , ` `)时,用法非常直观。
public class SplitExample {
public static void main(String[] args) {
String sentence = "apple,banana,orange,grape";
// 使用逗号 "," 作为分隔符
String[] fruits = sentence.split(",");
// 打印分割后的数组
for (String fruit : fruits) {
System.out.println(fruit);
}
// 输出:
// apple
// banana
orange
// grape
}
}
示例 2:使用多个字符作为分隔符
分隔符也可以是多个字符。
public class SplitExample2 {
public static void main(String[] args) {
String text = "apple-and-banana-or-orange";
// 使用 "and" 和 "or" 作为分隔符(这里需要用到正则表达式的或 "|")
String[] items = text.split("and|or");
for (String item : items) {
System.out.println(item);
}
// 输出:
// apple-
// banana-
// orange
}
}
重要注意事项(陷阱)
陷阱 1:regex 参数是正则表达式
这是 split() 方法最常见的“坑”,如果你想在分隔符中使用一些在正则表达式中有特殊含义的字符,必须进行转义。
常见正则特殊字符:
, , , , , , [, ], , , \, ^, ,
错误示例:
// 想要用 "." 分割 IP 地址,这是错误的!
String ip = "192.168.1.1";
String[] parts = ip.split("."); // 错误!
// 在正则中 "." 匹配的是任意字符,所以这会分割成 ["", "", "", "", "", "", "", ""]
正确示例:
必须使用反斜杠 \ 对 进行转义,在 Java 字符串中,反斜杠本身也需要转义,所以是 "\\."。
String ip = "192.168.1.1";
// 必须对 "." 进行转义
String[] parts = ip.split("\\.");
for (String part : parts) {
System.out.println(part);
}
// 输出:
// 192
// 168
// 1
// 1
陷阱 2:分割结果中的空字符串
如果分隔符出现在字符串的开头、结尾或连续出现,split() 方法会产生空字符串 。
示例:
public class SplitEmptyExample {
public static void main(String[] args) {
String text1 = ",apple,orange,";
String[] parts1 = text1.split(",");
System.out.println("分割字符串: '" + text1 + "'");
for (String part : parts1) {
System.out.println("['" + part + "']"); // 用 [] 包裹,便于识别空字符串
}
// 输出:
// 分割字符串: ',apple,orange,'
// [''] <- 开头的逗号产生了空字符串
// ['apple']
// ['orange']
// [''] <- 结尾的逗号产生了空字符串
System.out.println("--------------------");
String text2 = "a,,b,c";
String[] parts2 = text2.split(",");
System.out.println("分割字符串: '" + text2 + "'");
for (String part : parts2) {
System.out.println("['" + part + "']");
}
// 输出:
// 分割字符串: 'a,,b,c'
// ['a']
// [''] <- 连续的逗号产生了空字符串
// ['b']
// ['c']
}
}
高级用法
重载方法:limit 参数
split() 方法还有一个重载版本,可以接收第二个参数 limit,用于控制分割的次数。
方法签名:
public String[] split(String regex, int limit)
limit 参数的作用:
limit > 0:分割最多limit - 1次,结果数组的长度将不会超过limit。limit < 0:匹配模式将被应用尽可能多的次数,没有限制。limit = 0:匹配模式将被应用尽可能多的次数,并且结果中不包含空字符串(这是与limit < 0的唯一区别)。
示例:
public class SplitLimitExample {
public static void main(String[] args) {
String text = "one,two,three,four,five";
// limit = 2: 最多分割 1 次
String[] parts1 = text.split(",", 2);
System.out.println("limit = 2:");
for (String part : parts1) {
System.out.println("['" + part + "']");
}
// 输出:
// ['one']
// ['two,three,four,five'] <- 剩下的所有部分都在第二个元素里
System.out.println("--------------------");
// limit = 0: 移除末尾的空字符串
String textWithEmptyEnd = "a,b,c,,";
String[] parts2 = textWithEmptyEnd.split(",", 0);
System.out.println("limit = 0 (移除末尾空字符串):");
for (String part : parts2) {
System.out.println("['" + part + "']");
}
// 输出:
// ['a']
// ['b']
// ['c']
// 注意:末尾的空字符串被移除了
}
}
替代方案:StringTokenizer
虽然 split() 非常流行,但在某些场景下,java.util.StringTokenizer 类也是一个不错的选择。
与 split() 的主要区别:
- 性能:
StringTokenizer通常比split()性能更好,因为它不使用正则表达式,解析速度更快,在需要处理大量数据且对性能要求极高的场景下,可以考虑它。 - 分隔符处理:
StringTokenizer默认会跳过连续的分隔符,不会产生空字符串。"a,,b"会被分割为["a", "b"]。 - API:
StringTokenizer是一个迭代器风格的 API,通过hasMoreTokens()和nextToken()方法来获取分割后的字符串。
示例:
import java.util.StringTokenizer;
public class StringTokenizerExample {
public static void main(String[] args) {
String text = " apple, banana, , orange ";
// 创建 StringTokenizer,分隔符为逗号和空格
// 注意:默认会跳过连续的分隔符,并且不会包含开头和结尾的空白
StringTokenizer tokenizer = new StringTokenizer(text, ", ");
System.out.println("使用 StringTokenizer:");
while (tokenizer.hasMoreTokens()) {
System.out.println("Token: [" + tokenizer.nextToken() + "]");
}
// 输出:
// Token: [apple]
// Token: [banana]
// Token: [orange]
}
}
总结与最佳实践
| 特性 | String.split() |
StringTokenizer |
|---|---|---|
| 分隔符 | 正则表达式 | 普通字符 |
| 空字符串 | 可能产生 | 默认跳过 |
| 性能 | 较慢(因正则) | 较快 |
| API | 返回数组 | 迭代器风格 |
| 灵活性 | 极高,功能强大 | 一般,功能有限 |
| 适用场景 | 大多数常规情况,尤其是分隔符复杂或需要保留空字符串时 | 高性能要求的场景,分隔符简单且不需要空字符串 |
最佳实践建议:
- 首选
split():在绝大多数情况下,String.split()是你的首选,它的代码更简洁,功能更强大,尤其是在处理复杂的分隔符逻辑时。 - 注意转义:永远记住
split()的参数是正则表达式,如果分隔符是 , , 等特殊字符,一定要记得用\\进行转义。 - 处理空字符串:明确你的业务逻辑是否需要处理由开头、结尾或连续分隔符产生的空字符串,如果不需要,可以考虑使用
split(regex, 0)来自动移除它们。 - 性能瓶颈时考虑
StringTokenizer:如果你的代码性能分析显示split()是一个瓶颈,并且你的分隔符逻辑非常简单,那么可以尝试用StringTokenizer优化。 - 考虑 Java 8+ 的流式处理:如果你需要对分割后的结果进行进一步处理(如过滤、映射),结合 Java 8 的 Stream API 会非常方便。
// Java 8+ Stream API 示例
String text = "apple, banana, , orange";
Arrays.stream(text.split(",")) // 先分割
.map(String::trim) // 再修剪每个元素的空格
.filter(s -> !s.isEmpty()) // 过滤掉空字符串
.forEach(System.out::println);
// 输出:
// apple
// banana
// orange 