Java基础整理——String源码理解之indexOf(JDK1.7)

String的indexOf共有四种参数,分别如下图:

其中,第一种内部实现如下:

public int indexOf(int ch) {
        return indexOf(ch, 0);
    }

 

 实际就是调用了第三种方法,所以我们可以只关注第三种方法。而在此之前,需要知道的一点基础知识是在1.7中,String的实现是一个private final char value[];(此处为何用final网上解释众多,此处不详谈。而实际上个人感觉此数组构建略微留有一些C的痕迹)。接下来我们来看第三种方法的源码(为方便阅读修改了注释):

  public int indexOf(int ch, int fromIndex) {
            //此处value即为上述提到的String用于存储字符串的数组
           final int max = value.length;
           if (fromIndex < 0) {
               fromIndex = 0;
           } else if (fromIndex >= max) {
               // 如果开始长度大于等于数组长度,返回-1
               return -1;
           }
           //此处Character.MIN_SUPPLEMENTARY_CODE_POINT为Unicode的增补代码点的最小值。
           if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
               // handle most cases here (ch is a BMP code point or a
               // negative value (invalid code point))
               final char[] value = this.value;
               for (int i = fromIndex; i < max; i++) {
                   //此处value[i]实际上是一个char类型的值,此处比较时由于已知ch为基本多语言面 (BMP UBasic Multilingual Plane),
                   //即Unicode 的 16 位设计可以表示的字符,因此进行类型转换后可比较其值。
                   if (value[i] == ch) {
                       return i;
                   }
               }
               return -1;
           } else {
               return indexOfSupplementary(ch, fromIndex);
           }
       }

此处indexOfSupplementary方法的源码设计Character方面源码,此处暂不讨论。

而第二种方法实现如下:

  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 int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        //如果开始搜索的位置大于资源数组长度,直接返回资源数组长度(目标数组长度为0)或-1
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        //如果开始搜索位置小于0,则设为0
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        //如果目标数组长度为0,直接返回开始搜索位置。
        if (targetCount == 0) {
            return fromIndex;
        }
        //取到目标是数组的第一个char值
        char first = target[targetOffset];
        //取到最后一次搜索的位置
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            //取到第一个字符相同的位置
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            //循环比较接下来所有所有的字符,如果全部相同则返回第一个字符的位置
            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;
    }

 

posted @ 2017-10-03 18:18  豆豆323  阅读(2051)  评论(0编辑  收藏  举报