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

来源:互联网 发布:小黄鸭软件 编辑:程序博客网 时间:2024/06/05 05:04

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
}

0 0