给出答案,见下文——士气:永远不要.split()
单独打电话;如果你想要理智的行为,总是给它一个-1的长度参数。但不是0!
javadoc forPattern.split()
声明如下:
此方法返回的数组包含输入序列的每个子字符串,这些子字符串由与此模式匹配的另一个子序列终止或在输入序列的末尾终止。
见证这段代码:
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
}
现在,参考 javadoc,一个数组应该包含输入的子字符串,它们是(引用):
- “由与此模式匹配的另一个子序列终止”:嗯,有一个 - 下划线之前的空字符串(
UNDERSCORE
显然匹配); - 或“在输入序列的末尾终止”:也有一个:下划线后面的空字符串。
然而,上面的代码打印0
. 为什么?这是一个已知的错误?(imnsho 是的,见下文)还有哪些.split()
不遵守合同的情况?(再次,见下文)
答案(就在这个解释性文本的正下方)
使用 aPattern
时,单参数方法等效于使用作为参数.split()
调用双参数方法。0
这就是错误所在。如果参数为 0,则从数组“向下”到第一个非空元素的所有空字符串都将从结果中删除。
如果在阅读本文之前,您不知道什么是脑残的设计决策,那么现在您知道了。更危险的是,这是默认行为。
解决方案是始终使用该.split()
方法的完整形式并给它一个负长度参数。这里选择-1。在这种情况下,.split()
行为正常:
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
System.out.println(UNDERSCORE.split("__").length);
System.out.println(UNDERSCORE.split("_x_").length);
System.out.println(UNDERSCORE.split("_", -1).length);
System.out.println(UNDERSCORE.split("__", -1).length);
System.out.println(UNDERSCORE.split("_x_", -1).length);
}
输出:
0 # BUG!
0 # BUG!
2 # BUG!
2 # OK
3 # OK
3 # OK