类String中的边缘情况?

时间:2013-11-11 06:37:17

标签: java string substring

考虑以下情况:

String str = "str";
System.out.println("str subs: " + str.substring(3,3));

预期结果:
StringIndexOutOfBoundsException(因为beginIndex在“字符串结束后”开始)

实际结果:
打印空字符串

来自 String.java

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
}

很容易看出实施没有处理边缘情况,其中:
beginIndex == endIndex == countcount是字符串的长度)。

根据 the manual 方法substring:

  

返回一个新字符串,该字符串是此字符串的子字符串。子串   从指定的beginIndex开始并延伸到at处的字符   index endIndex - 1.因此子字符串的长度是   endIndex的-的beginIndex。

它还声明该方法抛出:

  

IndexOutOfBoundsException - 如果beginIndex为负数或endIndex   大于此String对象的长度,或者beginIndex是   大于endIndex。

makes sense 是否认为案例:beginIndex == endIndex == count有效? 我错过了什么吗?

3 个答案:

答案 0 :(得分:7)

"abc".substring(3,3) == ""

正如你所说,让我们看一下manual

  

返回一个新字符串,该字符串是此字符串的子字符串。

  

子字符串从指定的beginIndex开始,并扩展到索引endIndex的字符 - 1.

无论弦的长度如何,这句话的解释都很困难。但我认为我们可以同意空字符串不会违反这一点。

  

因此子串的长度是endIndex-beginIndex。

  

抛出:IndexOutOfBoundsException - 如果beginIndex为负数

它不是

  

或endIndex大于此String对象的长度

它不是

  

或beginIndex大于endIndex。

不是。

行为似乎是对我的承诺。

你也可以这样看:字符串"abc"包含四个空子串,两个字符之间,一个在开头,一个在结尾。可以分别通过substring1,12,20,0通过3,3访问它们。还要与以下代码比较

class EmptyTest {

    public static void main (String[] args) {

         Matcher m = Pattern.compile("").matcher("abc");
         while (m.find()) {
            System.out.println(m.start() + "," + m.end());
         }
    }
}

打印

0,0
1,1
2,2
3,3

答案 1 :(得分:2)

beginIndex == endIndex == count表示虚拟“开始游标”将紧跟在字符串中的最后一个字符之后,与“结束游标”位于同一点,因此您将获得一个零长度字符串。它似乎与返回(0,0)的空字符串一样有效。

答案 2 :(得分:0)

此行为与以下内容一致:

String str = "str";
System.out.println("str subs: " + str.substring(2,2));

还返回空字符串而不是子字符串。空集是所有集的子集。

引用类java.lang.String 参数: beginIndex起始索引,包括在内。