String源碼分析(replace、split)(三)

1.String的replace方法源碼:

 public String replace(char oldChar, char newChar) {

//判斷替換字符和被替換字符是否相同
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;

//將源字符串轉換爲字符數組
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {

//判斷第一次被替換字符串出現的位置
                if (val[i] == oldChar) {
                    break;
                }
            }

//從出現被替換字符位置沒有大於源字符串長度
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {

//將源字符串,從出現被替換字符位置前的字符將其存放到字符串數組中
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];

  //開始進行比較;如果相同的字符串替換,如果不相同按原字符串
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }

//使用String的構造方法進行重新創建String
                return new String(buf, true);
            }
        }
        return this;
    }

2.String的split方法源碼:

JDK提供了split的重載方法如下:

  public String[] split(String regex) {
        return split(regex, 0);
    }

//通過正則表達式進行匹配字符串

  public String[] split(String regex, int limit) {
        char ch = 0;
        if (((regex.count == 1 &&
                ".$|()[{^ *+\\".indexOf(ch = regex.charAt(0)) == -1) ||
                (regex.length() == 2 && regex.charAt(0) == '\\' &&(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&   
  // 這種判斷是 ch < '0' && ch > '9' 時, 返回 true ,  也就是: (負數 | 負數) <0 ; 下同理
 ((ch-'a')|('z'-ch)) < 0 && ((ch-'A')|('Z'-ch)) < 0)) && (ch < Character.MIN_HIGH_SURROGATE ||  ch > Character.MAX_LOW_SURROGATE))
 //  utf-16 編碼中的 unicode 高代理項代碼單元的最小值。高代理項也稱爲前導代理項。
        {  int off = 0;
int next = 0;
boolean limited = limit > 0;
  ArrayList<String> list = new ArrayList$amp; 
 while ((next = indexOf(ch, off)) != -1) {
 if (!limited || list.size() < limit - 1) {
 list.add(substring(off, next));
 off = next + 1;
    } else {            

 // last one ,如果傳入返回數組長度,則 打到限制長度後,添加off 到原字符串末尾的字符串。
 //assert (list.size() == limit - 1);
 list.add(substring(off, count));
 off = count;
 break;
 }
            }
   // If no match was found, return this
 if (off == 0)
  return new String[] { this };
 // Add remaining segment
 if (!limited || list.size() < limit)   

// 問題2的解答:如果未到長度限制,或者未傳入第二個參數,添加 off 到末尾的字符串
  list.add(substring(off, count));
// Construct result
 int resultSize = list.size();
 if (limit == 0)
while (resultSize > 0 && list.get(resultSize-1).length() == 0)  
 resultSize--;
// 問題1解答:如果我們不傳入split的第二個參數,或者傳0,那麼最後此方法會從添加的最後一個元素開始,循環刪除掉長度爲0的“”字符串直到遇到第一個不爲空的字符串(從後面開始的,所以就是遇到最後一個不爲空的字符串時,停止刪除),;
String[] result = new String[resultSize];
 return list.subList(0, resultSize).toArray(result);
  }
 return Pattern.compile(regex).split(this, limit); 
  // 關於這個的話,需要了解一下正則表達式了,我給一篇好問題:https://my.oschina.net/u/1187481/blog/215379
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章