Java字符串split()方法的奇怪行为



我有一个方法,它接受一个字符串参数,并按#分割字符串,分割后将打印数组的长度和数组元素。下面是我的代码

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)返回"英里"(而不是"英里")

希望这能有所帮助。

最新更新