String.indexOf源码分析

转自:https://blog.csdn.net/liuyang755855737/article/details/78308537

最近看了下String的一些源码,觉得indexOf(String str)这个方法有点意思,这个方法的功能是找到当前字符串中第一次出现str的位置,返回int表示位置。试想一下,如果不看源码,我们自己实现一个这样的方法,我们会怎么做呢?
先说下我的思路:
1.遍历当前字符串,找到当前字符串中和str字符串第一个字符相同的字符,比如当前字符串为"abcdabcdefg",str为"def",那么我需要找到当前字符串中第一个d出现的位置,用变量存下来。
2.比较接下来的字符是否完全相同,这里我们发现当前字符串中第一个d出现的位置为3(从0开始计数),比较接下来的字符发现和str不相等,那么我们继续往下找d出现的位置。
3.当我们找到第二个d出现的位置,即当前字符串的第7个字符,继续和str比较,这里我们发现是相同的,返回7结束。
4.如果始终找不到相同的元素,且当前字符串遍历完毕,那么返回-1表示没找到。
接下来我们看看String类里的indexOf的源码实现:

    public int indexOf(String str) {
        return indexOf(str, 0);
    }
 
    public int indexOf(String str, int fromIndex) {
        return indexOf(value, 0, value.length,
                str.value, 0, str.value.length, fromIndex);
    }
    //核心实现代码 为什么用static修饰呢?有点疑惑
    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 */
            //再次判断下边界,如果大于边界就可以直接返回-1了
            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;
    }

这个方法首先会查找子字符串的头字符在此字符串中第一次出现的位置,再以此位置的下一个位置开始,然后将子字符串的字符依次和此字符串中字符进行比较,如果全部相等,则返回这个头字符在此字符串中的位置;如果有不相等的,则继续在剩下的字符串中查找,继续进行上面的过程,直到查找到子字符串或没有找到返回-1为止。
感兴趣的同学可以自己实现以下这个功能,顺便说下String里的一个思想,比如replace方法我们知道是将当前字符串中的某个字符替换成另一个字符,String里都会先遍历以下当前字符串,看看是否有需要改变的,如果没有就直接返回,如果需要改变,就把需要改变的第一个字符前的数据完全拷贝到新字符中(因为前面的都不需要替换),接下来的数据拷贝的时候进行判断是否替换,再拷贝。也是一个比较好的思想。

猜你喜欢

转载自blog.csdn.net/Dongguabai/article/details/83303102