tags:

views:

302

answers:

5

I came across some substring() method mystery and not sure why it is not throwing out of index error. The string "abcde" has index start from 0 to 4 but substring() method takes startIndex and endIndex as arguments which I believe zero base based on the fact that I can call foo.substring(0) and get "abcde"

Then why substring(5) works??? That index should be out of range. Could anyone explain to me?

        /*
         * 01234
         * abcde
         */
        String foo = "abcde";
        System.out.println(foo.substring(0));
        System.out.println(foo.substring(1));
        System.out.println(foo.substring(2));
        System.out.println(foo.substring(3));
        System.out.println(foo.substring(4));
        System.out.println(foo.substring(5));
        System.out.println("-----------------");

This code outputs:

abcde
bcde
cde
de
e
               //foo.substring(5) output nothing here, isn't this out of range?
-----------------

The last one foo.substring(5) is pointing of non existing index but it does not throw an error. But when I replace 5 with 6,

foo.substring(6)

Then I get error:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
+2  A: 

substring(5) points to an existing index...it just happens to point to an empty string. substring(6), on the other hand, is just crazy talk. :)

Faisal
+4  A: 

When you do foo.substring(5), it gets the substring starting at the position right after the "e" and ending at the end of the string. Incidentally, the start and end position happen to be the same. Thus, empty string. You can think of the index as being not an actual character in the string, but a position in between characters.

        ---------------------
String: | a | b | c | d | e |
        ---------------------
Index:  0   1   2   3   4   5
Jeff
+4  A: 

According to the Java API doc, substring throws an error when the start index is greater than the Length of the String.

IndexOutOfBoundsException - if beginIndex is negative or larger than the length of this String object.

In fact, they give an example much like yours:

"emptiness".substring(9) returns "" (an empty string)

I guess this means it is best to think of a Java String as the following, where an index is wrapped in |:

|0| A |1| B |2| C |3| D |4| E |5|

Which is to say a string has both a start and end index.

Graphain
Ahh! thanks for the tip guys, I was looking at same doc page but didn't know I had to scroll down all the way to get more detail...
masato-san
+1  A: 

It's because the substring function returns an "inclusive" substring. So the index 5 points to a location BEFORE the end of the string, but AFTER the last displaying character of the string.

This is shown in the documentation: http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/lang/String.html#substring(int)

Josiah
+1  A: 

From String API javadoc:

===

substring

public String substring(int beginIndex) Returns a new string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.

Examples:

"unhappy".substring(2) returns "happy" "Harbison".substring(3) returns "bison" "emptiness".substring(9) returns "" (an empty string)

Parameters: beginIndex - the beginning index, inclusive. Returns: the specified substring. Throws: IndexOutOfBoundsException - if beginIndex is negative or larger than the length of this String object.

====

So this is by design. if you give the index as the size of the string, it returns empty string.

Samit G.