2

I'm reading the source code of String.class.
In the method indexOf() I see something I can't understand.
Here is the method indexOf() code snippet from String.class source code.

/**
 * Code shared by String and StringBuffer to do searches. The
 * source is the character array being searched, and the target
 * is the string being searched for.
 *
 * @param   source       the characters being searched.
 * @param   sourceOffset offset of the source string.
 * @param   sourceCount  count of the source string.
 * @param   target       the characters being searched for.
 * @param   targetOffset offset of the target string.
 * @param   targetCount  count of the target string.
 * @param   fromIndex    the index to begin searching from.
 */
static int indexOf(char[] source, int sourceOffset, int sourceCount,
        char[] target, int targetOffset, int targetCount,
        int fromIndex) {
    if (fromIndex >= sourceCount) {
        return (targetCount == 0 ? sourceCount : -1);
    }
    if (fromIndex < 0) {
        fromIndex = 0;
    }
    if (targetCount == 0) {
        return fromIndex;
    }

    char first = target[targetOffset];
    int max = sourceOffset + (sourceCount - targetCount);

    for (int i = sourceOffset + fromIndex; i <= max; i++) {
        /* Look for first character. */
        if (source[i] != first) {
            while (++i <= max && source[i] != first);
        }

        /* Found first character, now look at the rest of v2 */
        if (i <= max) {
            int j = i + 1;
            int end = j + targetCount - 1;
            for (int k = targetOffset + 1; j < end && source[j]
                    == target[k]; j++, k++);

            if (j == end) {
                /* Found whole string. */
                return i - sourceOffset;
            }
        }
    }
    return -1;
}

I can't understand the code here.

if (fromIndex >= sourceCount) {
    return (targetCount == 0 ? sourceCount : -1);
}

If the source String is "abcdedefg", sourceOffset is 2, sourceCount is 3, and I want to search "d" from this, why can't I search from index 4?
/**
* Ps:If the sourceCount means the length of the whole string, why not use source.length
* instead ?
*/

5
  • 1
    Don't post pictures of code, post code. Why: meta.stackoverflow.com/q/285551/157247 Commented Nov 17, 2017 at 7:17
  • I have downvoted this question because you have posted an image of code and/or errors, rather than the text itself. Images are harder for everyone to use, including volunteers and future visitors. If you remove the image and replace it with the relevant text, I will consider retracting my downvote. See: Why not to upload images of code on SO when asking a question? Commented Nov 17, 2017 at 7:18
  • 1
    I'm sorry i don't know this. I'm modifying. Commented Nov 17, 2017 at 7:20
  • We have no idea what lines are "1756 to 1758" Commented Nov 17, 2017 at 7:28
  • @JimGarrison there was a criticized picture, that did show the line numbers for this purpose; the OP now entirely corrected the question. Commented Nov 17, 2017 at 7:43

2 Answers 2

4

This method accepts two character arrays - the source array is the one being searched and the target array is the one being searched for.

However, the offset and count variables limit the search to a sub-array of the source and a sub-array of the target.

Basically you are searching in the sub-array from source[sourceOffSet] to source[sourceOffset+sourceCount-1] for the String comprised of the characters in the sub-array from target[targetOffSet] to target[targetOffset+targetCount-1].

Here's an illustration. The relevant arrays for the search are the sub-arrays:

source array : |--------------------|
sub array    :       |-------|        
                   source  source
                   offset  offset +
                           source
                           count - 1

target array : |--------------------|
sub array    :       |-------|        
                   target  target
                   offset  offset +
                           target
                           count - 1

However, the search is further limited by supplying fromIndex. You start the search from the fromIndex'th index of the source sub-array.

Since the length of the source sub-array is sourceCount, if fromIndex >= sourceCount, the target sub-array cannot be found, so unless the target sub-array is empty (i.e. targetCount == 0), -1 is returned.

Let's consider your example:

source : "abcdedefg"
sourceOffset : 2
sourceCount : 3
target : "d"
targetOffset : 0
targetCount : 1
fromIndex : 4

These parameters mean you are searching in the source sub-string "cde" for the target sub-string "d" starting from index 4. However, there is no index 4 in "cde", so -1 is returned.

Regarding your

Ps:If the sourceCount means the length of the whole string, why not use source.length instead

As I explained sourceCount doesn't mean the length of the whole source array, just the length of the sub-array being searched.

Note that when you call someString.indexOf(str,fromIndex), the static method you asked about is being called with the following parameters:

public int indexOf(String str, int fromIndex) {
    return indexOf(value, 0, value.length,
            str.value, 0, str.value.length, fromIndex);
}

In this case sourceCount is equal to source.length (i.e. the entire source array is being searched starting at fromIndex).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. So the fromIndex is starting from the offset character, it's not the index of the whole string but the index of this substring ,from 0 ~~ "cde" has relative index 0,1,2 . Is that so?
@Saber that's correct. You can also see that from the for loop starting at int i = sourceOffset + fromIndex.
0
    if (fromIndex >= sourceCount) {
        return (targetCount == 0 ? sourceCount : -1);
    }

This says that in the search index (fromIndex) is after the end, string length (sourceCount), then return -1 (not found) unless the sought string is "" - which is "always found." Quite specific.

2 Comments

sourceCount means the end of the string? I thought it was the end of a substring.
Indeed, the javadoc above is a bit ambiguous: source the characters being searched. could mean both, but target the characters being searched for. makes it clear that source is the large string, and target the search key. They should have used "sought key" or such.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.