1. 程式人生 > >String源碼理解之indexOf(JDK1.7)

String源碼理解之indexOf(JDK1.7)

static img nta from 來看 png val 四種 targe

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;
    }

String源碼理解之indexOf(JDK1.7)