我有一个方法,它接受一个字符串参数,并按#分割字符串,分割后将打印数组的长度和数组元素。下面是我的代码
public void StringSplitTesting(String inputString) {
String tokenArray[] = inputString.split("#");
System.out.println("tokenArray length is " + tokenArray.length
+ " and array elements are " + Arrays.toString(tokenArray));
}
情况I:现在,当我的输入为abc#时,输出为tokenArray length is 1 and array elements are [abc]
情况II:但当我的输入为#abc时,输出为tokenArray length is 2 and array elements are [, abc]
但我希望这两种情况的输出相同此实现背后的原因是什么?为什么split()方法的行为是这样的?有人能给我一个恰当的解释吗?
单参数split
方法行为的一个方面可能令人惊讶——从返回的数组中丢弃尾随的null。
因此,尾随的空字符串不包括在结果数组中。
要获得每种情况的长度2
,可以向两个参数的split
方法传递一个负的第二个参数,这意味着长度是不受限制的,并且不会丢弃任何尾随的空字符串。
只需查看文档:
因此,结果中不包括尾随的空字符串大堆
因此,在情况1中,输出将是{"abc", ""}
,但Java会剪切后面的空String。如果不希望丢弃尾部的空字符串,则必须使用split("#", -1)
。
观察到的行为是由于Java中substring()方法固有的不对称性:
这是split():实现的核心
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
理解上述代码行为的关键是理解substring()方法的行为:
来自Javadocs:
字符串java.lang.String.substring(int beginIndex,int endIndex)
返回作为此字符串的子字符串的新字符串。子字符串从指定的beginIndex开始,延伸到索引处的字符endIndex-1。因此,子字符串的长度是endIndex beginIndex。
示例:
"汉堡包"。子字符串(4,8)返回"催促"(而不是"汉堡")
"微笑"。子字符串(1,5)返回"英里"(而不是"英里")
希望这能有所帮助。