1. 程式人生 > >String原始碼閱讀之contains實現原理

String原始碼閱讀之contains實現原理

本文將對String部分原始碼進行閱讀分析的記錄。

contains

對String中的contains方法進行分析,瞭解其採用的是什麼演算法進行匹配。

//用於判斷源字串是否包含目標字元序列 CharSequence s
 public boolean contains(CharSequence s) {
         //呼叫indexOf(String str)方法
        return indexOf(s.toString()) > -1;
    }

indexOf (String str)

    public int indexOf(String str) {
    //繼續往下呼叫indexOf(String str, int fromIndex)方法,並傳入匹配起始下標
return indexOf(str, 0); }

indexOf (String str, int fromIndex)

    public int indexOf(String str, int fromIndex) {
        //繼續往下呼叫indexOf(char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount,int fromIndex) 函式
        //傳入源字串,源字串偏移量,源字串長度,目標字串,目標字串偏移量,目標字串長度,匹配源字串的起始座標
return indexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex); }

indexOf (char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount,int fromIndex)

static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int
targetOffset, int targetCount, int fromIndex) { //若匹配的起始下標大於或等於源字串的長度 if (fromIndex >= sourceCount) { //檢測目標長度是否為0,是則返回源字串長度,否則返回-1 return (targetCount == 0 ? sourceCount : -1); } //若匹配的起始下標小於0 if (fromIndex < 0) { //將匹配的起始下標置0 fromIndex = 0; } //若目標字串長度等於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++); //j能一直增加到end,說明已經成功匹配 if (j == end) { /* Found whole string. */ //返回在源字串中被匹配到的第一個字元的下標。 return i - sourceOffset; } } } //沒有匹配到,返回-1 return -1; }

  從這個方法中可以看出,其採用的是最原始也是最笨的方法進行匹配,將目標字串與源字串的字元進行逐一匹配,若第一個字元匹配成功,則進行餘下的匹配,若餘下的匹配不成功,則從一開始目標字串的第一個字元與源字串匹配時的下標的下一位繼續進行匹配。這樣其實是浪費了很多沒必要的時間。有關字串匹配的快捷有效匹配演算法,可以參照KMP演算法