string.split()默认丢弃末尾空字符串,如"a,b,c,".split(",")返回["a","b","c"];要保留所有空串(含首、中、尾),必须显式传负数限制参数,如split(",", -1)。

Java里String.split()遇到空字符串会怎样
默认情况下,String.split()会丢弃末尾的空字符串元素。比如"a,b,c,".split(",")结果是长度为3的数组:["a", "b", "c"],最后那个空串直接没了。
这不是bug,是JDK的明确行为:当不传限制参数(或传0)时,它等价于调用split(regex, 0),而该重载会自动截断末尾所有匹配分隔符产生的空项。
- 常见错误现象:
"|||".split("\|")返回空数组[],不是["", "", "", ""] - 使用场景:解析CSV、日志字段、配置项时,若原始数据末尾有分隔符,容易漏掉“空值语义”
- 根本原因:正则匹配后生成的字符串数组被
Arrays.copyOf截断了尾部空项
想要保留所有空字符串?必须传负数限制参数
唯一可靠方式是显式传一个负数给第二个参数,比如-1。这时split()会返回全部分割结果,包括开头、中间、末尾的空字符串。
-
"a,,b,".split(",", -1)→["a", "", "b", ""] -
"|a|b|".split("\|", -1)→["", "a", "b", ""] - 注意:不能用
1或0,1只返回1个元素(整个原串),0就是默认行为(丢尾空) - 性能影响极小,只是不调用截断逻辑,无额外正则或内存开销
用Pattern.compile().split()更可控但没必要
有人想用Pattern预编译来提升多次调用性能,或者加Pattern.LITERAL避免转义麻烦。但对纯分隔符场景,这反而增加复杂度。
立即学习“Java免费学习笔记(深入)”;
- 如果分隔符是固定字符串(如
"|"、":"),优先用String.split(regex, -1),别自己绕路编译Pattern -
Pattern.compile("\|").split("a|b||", -1)结果和"a|b||".split("\|", -1)完全一致,没额外收益 - 只有当你需要复用同一正则做其他操作(如
matcher.find())时,才值得提前编译
特殊字符做分隔符必须转义,否则行为出人意料
像.、|、+、*这些在正则里有含义的字符,不转义就会按正则逻辑匹配,不是字面意思分割。
-
"a.b.c".split(".")→ 返回空数组[],因为.匹配任意字符,整个串全被“吃掉”了 - 正确写法是
"a.b.c".split("\.")或"a.b.c".split(Pattern.quote("."), -1) - 最安全的习惯:只要分隔符不是字母数字或下划线,就老老实实用
Pattern.quote(sep)包一层,再拼, -1
"a|b|".split("\|")返回["a","b"]时,你得意识到——不是代码错了,是Java默认帮你“优化”掉了语义上重要的空字段。










