replace(char oldChar, char newChar)源码分析

简介: 一String中的replace(char oldChar, char newChar)源码以下是JRE中源码,分析在第二部分,将全面分析这个方法。

一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;
    }
相关文章
|
1月前
|
C++
无法将参数1从“const char [6]”转换为“char *”的解决方法
无法将参数1从“const char [6]”转换为“char *”的解决方法
|
9月前
|
存储
char *p 与char p[] 比较
char *p 与char p[] 比较
94 0
【C/C++ strlen(str)和str.length()和str.size()的区别】
strlenQ(str)和str.length()和str.size()都可以求字符串长度,返回字符串中字符的长度,不包括0'。其中str.length()和str.size()是同义词,返回同样的值。
【C/C++ strlen(str)和str.length()和str.size()的区别】
char*转为LPCWSTR
char*转为LPCWSTR
73 0
|
C++
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
129 0
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
627 0
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
|
C++ Linux
const char*, char const*, char*const的区别
const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目。 这个知识易混点之前是看过了,今天做Linux上写GTK程序时又出现个Warning,发散一下又想到这个问题,于是翻起来重嚼一下。 事实上这个概念谁都有只是三种声明方式非常相似: Bjarne在他的The C++ Programming Language里面给出过一个助
1171 0
捋一捋 const char * p / char* const p / char const* p
const int *p 与 int const *p 是一样的,即 *p 是常量; 而 int * const p 跟上面是不一样的,即 p 是常量; 我们知道引用只是一个别名,与变量共享存储空间,并且必须在定义的时候初始化,而且不能再成为别的变量的别名,这让我们想到什么呢,貌似跟  int * const p   的性质很像。
1184 0