String源碼理解之indexOf(JDK1.7)
阿新 • • 發佈:2017-10-03
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(intch, 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)