一String中的replace(char oldChar, char newChar)源码
- 以下是JRE中源码,分析在第二部分,将全面分析这个方法。每一行都有注解。
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++;
}
return new String(buf, true);
}
}
return this;
}
二源码解释和分析
//源码分析,这个是String的替代字符的方法
//例如: s:"hi" s.replace('h','g') --》s:"gi"
//oldChar 前者是希望被替换的字符 newChar 后者是希望被替换成的字符
public String replace(char oldChar, char newChar) {
//当oldChar和newChar不同时,才替换,不然没有意义
if (oldChar != newChar) {
//value是String的私有字符常量 value[]的引用名
//private final char value[];
int len = value.length;
int i = -1;
//因为value是不可变常量,需要重新创建一个char[] 用以构建新的String
char[] val = value; /* avoid getfield opcode */
//i初始值-1 ++i 先加后进行逻辑运算,这个时候 0 1 2 ...只要小于
while (++i < len) {
if (val[i] == oldChar) {
//break的作用是跳出当前循环块(for、while、do while)或程序块(switch)
//如果出现了原来String的oldChar的位置,直接跳出循环
//以“hi”为例,s.replace('h','g')
//val[0] == ‘h’
// ‘h’ == ‘h’--》 true跳出循环,此时i=0 逻辑的目的是为了定位旧字符的位置
break;
}
}
//以“hi”为例,s.replace('h','g')
//此时i=0 开始进行替换
if (i < len) {
//先创建一个新的字符数组,长度与原String相同。
char buf[] = new char[len];
//以“hi”为例,s.replace('h','g') 这部分不循环
//这段循环是在找到原String的第一个需要被替代的字符后,将前面部分的字符,直接循环赋值给新char buf[]
//这个新的字符数组buf[],新创建的String就是基于这个buf[]来创建的。
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
// 以“hi”为例,s.replace('h','g') i=0,1 len=2 循环下去
while (i < len) {
//将定位到的旧字符附给 c,目的是c == oldChar进行逻辑判断,区分newChar和不需要替换的字符
char c = val[i];
//找到旧字符用新的字符替换掉
buf[i] = (c == oldChar) ? newChar : c;
//i++,可以知道的是,将字符串的每一个字符串都进行了逻辑判断。
i++;
}
//最后得到了一个新的字符数组buf[i] 是这种格式的['g','i']
//String底层是基于字符数组实现的,用buf[i]实例化一个新的String。
return new String(buf, true);
//逻辑为什么是这样,这是源码工程师的尊严和高度
}
}
return this;
}