String.split()
这是将一个字符串根据指定的分隔符(或正则表达式)拆分成一个字符串数组 (String[]) 的最直接方法。

基本语法
public String[] split(String regex)
regex: 分隔符。注意:这里是一个正则表达式,而不仅仅是普通字符。
示例 1:使用普通字符作为分隔符
当分隔符是简单的字符(如 , , , 空格等)时,split() 的行为非常直观。
String sentence = "apple,banana,orange,grape";
String[] fruits = sentence.split(",");
// 输出结果
for (String fruit : fruits) {
System.out.println(fruit);
}
// 输出:
// apple
// banana
// orange
// grape
示例 2:使用多个字符作为分隔符
分隔符可以是多个字符组成的字符串。
String data = "apple-+-banana-+-orange";
String[] items = data.split("-+-");
for (String item : items) {
System.out.println(item);
}
// 输出:
// apple
// banana
// orange
示例 3:使用正则表达式作为分隔符
这是 split() 功能强大的地方,但也容易出错,当分隔符本身是正则表达式的特殊字符时,必须进行转义。
常见的正则元字符:
, , , , , ^, , , , [, , \, ],

错误示范: 你想用 作为分隔符,但 在正则中表示“任意字符”,所以结果可能不是你想要的。
String ip = "192.168.1.1";
// 错误写法: "." 匹配任意字符,会得到 ["", "", "", "", "", "1"]
String[] parts1 = ip.split(".");
// 输出可能是一个很长的数组,因为 "192" 会被拆分成 ["1", "9", "2", ...]
// 正确写法: 使用 "\\" 对 "." 进行转义
String[] parts2 = ip.split("\\.");
for (String part : parts2) {
System.out.println(part);
}
// 输出:
// 192
// 168
// 1
// 1
转义规则:
在 Java 字符串中,一个反斜杠 \ 是一个转义字符,要在字符串中表示一个字面上的反斜杠 \,你需要写成 \\,而正则表达式中的转义也是用 \,要表示一个正则表达式的转义字符(如 \.),在 Java 字符串中你需要写成 "\\\\"。
另一个例子:用 分隔 在正则中表示“或”。
String choices = "A|B|C|D";
// 错误写法: "|" 会被当作 "或" 操作符
String[] options1 = choices.split("|");
// 输出: ["", "", "", "", "A", "|", "B", "|", "C", "|", "D"] (结果很奇怪)
// 正确写法: 对 "|" 进行转义
String[] options2 = choices.split("\\|");
for (String option : options2) {
System.out.println(option);
}
// 输出:
// A
// B
// C
// D
split() 的高级用法:限制分割次数
split() 方法还有一个重载版本,可以指定分割的最大次数。

public String[] split(String regex, int limit)
limit: 分割的次数限制。limit > 0: 最多分割limit - 1次,数组的长度不会超过limit。limit < 0: 分割次数没有限制,与split(regex)相同。limit == 0: 分割次数没有限制,并且会忽略末尾的空字符串,这是与limit < 0的一个关键区别。
示例 4:使用 limit 参数
String csvLine = "a,b,c,,d,"; // 注意末尾的逗号
// limit > 0, 3
String[] parts1 = csvLine.split(",", 3);
// 只分割前2个逗号,剩余部分作为一个整体
// 结果: ["a", "b", "c,,d,"]
System.out.println("Limit=3: " + Arrays.toString(parts1));
// limit < 0, -1
String[] parts2 = csvLine.split(",", -1);
// 完全分割,保留所有空字符串
// 结果: ["a", "b", "c", "", "d", ""]
System.out.println("Limit=-1: " + Arrays.toString(parts2));
// limit = 0
String[] parts3 = csvLine.split(",", 0);
// 完全分割,但忽略末尾的空字符串
// 结果: ["a", "b", "c", "", "d"]
System.out.println("Limit=0: " + Arrays.toString(parts3));
相关方法:StringTokenizer
这是一个更老、更底层的类,在处理简单分隔符时比 split() 性能可能更好,但功能较弱,且被认为是遗留类。
- 特点:
- 默认分隔符是空白字符(空格、制表符、换行、回车)。
- 不能使用正则表达式。
- 默认会忽略连续的分隔符和前后的分隔符(不像
split()会保留空字符串)。
import java.util.StringTokenizer;
String text = " apple, banana, orange, ";
StringTokenizer tokenizer = new StringTokenizer(text, ","); // 使用逗号作为分隔符
while (tokenizer.hasMoreTokens()) {
System.out.println(tokenizer.nextToken());
}
// 输出 (自动去除了前后和中间多余的空格):
// apple
// banana
// orange
推荐: 在新代码中,除非有性能瓶颈或特殊需求,否则优先使用 String.split(),因为它更符合现代 Java 的编程风格,功能也更强大。
使用 Java 8 Stream API 进行分割
对于更复杂的场景,比如分割后需要立即进行过滤或转换,可以使用 Stream API。
import java.util.Arrays;
import java.util.stream.Collectors;
String data = "1,2,3,empty,4,5,";
// 1. 分割
// 2. 过滤掉 "empty" 字符串和 null
// 3. 将字符串转换为整数
// 4. 收集到一个 List 中
List<Integer> numbers = Arrays.stream(data.split(","))
.map(String::trim) // 去除每个元素两端的空格
.filter(s -> !"empty".equals(s) && !s.isEmpty()) // 过滤
.map(Integer::parseInt) // 转换
.collect(Collectors.toList());
System.out.println(numbers); // 输出: [1, 2, 3, 4, 5]
总结与最佳实践
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
String.split() |
功能强大,支持正则表达式,语法简洁,是标准做法。 | 分隔符是正则表达式,特殊字符需要转义,可能产生空字符串。 | 绝大多数情况下的首选。 |
StringTokenizer |
性能可能稍好,对于简单分隔符处理直观。 | 功能有限(不支持正则),是遗留类,API 较旧。 | 简单、性能敏感的场景,或维护旧代码。 |
Stream API |
极其灵活,可以无缝衔接后续的过滤、映射、聚合等操作。 | 语法相对复杂,对于简单分割有点“杀鸡用牛刀”。 | 需要在分割后立即进行复杂处理的流式操作。 |
最佳实践建议:
- 首选
String.split():这是最通用、最符合现代 Java 编程习惯的方法。 - 记住转义:如果你的分隔符是 , , 等正则元字符,一定要记得用
\\进行转义,split("\\.")。 - 处理空字符串:
split()总是会保留由连续分隔符产生的空字符串,如果你需要忽略它们,可以在split后手动过滤,或者使用split(regex, 0)来自动忽略末尾的空字符串。 - 复杂操作用 Stream:如果分割只是数据处理的第一步,后面跟着过滤、转换等,直接使用
Arrays.stream(split(...))会非常方便。
