研读StringBuilder的源码

1. append方法:

代码:

public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
public AbstractStringBuilder append(String str) {//String可以改成其他的类型
        if (str == null)
            return appendNull();//如果str是空的,则返回null
        int len = str.length(); //定义str的长度
        ensureCapacityInternal(count + len);
//通过ensureCapacityInternal方法确保有足够的空间,如果没有则需要重新开辟空间。
        str.getChars(0, len, value, count); //将str数组从0到len复制到value中,偏移量为count(从第count个开始复制)
        count += len;                       //为已使用的字符数,将其加上复制的字符串长度
        return this;                        //返回复制好的数组
    }

其中getChars(0, len, value, count);中 0为 srcBegin, len为 srcEnd, value为 dst,count为 dstBegin

2.delete方法:

代码:

 public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }

public AbstractStringBuilder delete(int start, int end) {//start为起始位置,end为结束位置
        if (start < 0)        如果起始位置小于0,抛出角标越界错误
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            end = count;      如果结束位置大于原字符串的最大长度,end就等于最大长度
        if (start > end)      如果起始位置大于结束位置,抛出角标越界错误
            throw new StringIndexOutOfBoundsException();
        int len = end - start;//要删除字符串的长得4度
        if (len > 0) {        //如果要删除字符串的长度大于0,也就是一个以上,则进行删除
            System.arraycopy(value, start+len, value, start, count-end);
通过System.arraycopy来实现,即把 end 后面的字符串复制到 start 位置,即相当于将中间的字符删掉。 
            count -= len;     //最终长度
        }
        return this;          //返回最终的结果
    }

其中有个arraycopy()方法

它可以实现将一个数组的指定个数元素复制到另一个数组中

举例:

Int[] arr1 ={1,2,3,4,5};

arrayCopy(arr1, 3, arr1, 2, 2);

意思是:将arr1从数字4开始 拷贝到arr1的数字3的位置, 拷贝2个数, 也就是说将4和5 拷贝到数字3的位置,相当于删除数字3.
 

System.arraycopy(src, srcPos, dest, destPos, length);

src表示源数组

srcPos表示源数组中拷贝元素的起始位置。

dest表示目标数组

destPos表示拷贝到目标数组的起始位置

length表示拷贝元素的个数

需要注意的是在进行数组拷贝时,目标数组必须有足够的空间来存放拷贝的元素,否则就会发生角标越界异常。

3.appendCodePoint方法:

该方法用于往 StringBuilder 对象中添加代码点。代码点是 unicode 编码给字符分配的唯一整数,unicode 有17个代码平面,其中的基本多语言平面(Basic Multilingual Plane,BMP)包含了主要常见的字符,其余平面叫做补充平面。

所以这里先通过Character.isBmpCodePoint判断是否属于 BMP 平面,如果属于该平面,此时只需要2个字节,则直接转成 char 类型并添加到 StringBuilder 对象。如果超出 BMP 平面,此时需要4个字节,分别用来保存 High-surrogate 和 Low-surrogate,通过Character.toChars完成获取对应4个字节并添加到 StringBuilder 对象中。

代码:

public StringBuilder appendCodePoint(int codePoint) {
        super.appendCodePoint(codePoint);
        return this;
    }

public AbstractStringBuilder appendCodePoint(int codePoint) {
        if (Character.isBmpCodePoint(codePoint)) {
            return append((char)codePoint);
        }
        return append(Character.toChars(codePoint));
    }

4.deleteCharAt方法

删除指定索引字符,与 delete 方法实现一样,通过shift方法实现删除,修改 count 值。

代码:

public StringBuilder deleteCharAt(int index) {
        super.deleteCharAt(index);
        return this;
    }

public AbstractStringBuilder deleteCharAt(int index) {
        checkIndex(index, count);
        shift(index + 1, -1);
        count--;
        return this;
    }

5.replace方法:

该方法用于将指定范围的字符替换成指定字符串。

代码:

public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }
 
public AbstractStringBuilder replace(int start, int end, String str) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (start > count)
            throw new StringIndexOutOfBoundsException("start > length()");
        if (start > end)
            throw new StringIndexOutOfBoundsException("start > end");
//以上都在检查范围合法性:是否角标越界?

        if (end > count)//end 不能大于已使用字符数 count,大于的话则令其等于 count。 
            end = count;
        int len = str.length();
        int newCount = count + len - (end - start);//计算新的count
        ensureCapacityInternal(newCount);

        System.arraycopy(value, end, value, start + len, count - end);
//通过arraycopy()方法把 end 后面的字符串复制到 end + (newCount - count) 位置。 
        str.getChars(value, start);//将字符串放到 start 后,直接覆盖掉后面的若干字符。
        count = newCount;
        return this;
    }

6.insert方法:

该方法用于向 StringBuilder 对象中插入字符。根据传入的参数类型有若干个 insert 方法,操作都相似,深入看重点一个。

代码:

public StringBuilder insert(int offset, String str) {
        super.insert(offset, str);
        return this;
    }
public AbstractStringBuilder insert(int offset, String str) {
        if ((offset < 0) || (offset > length()))//检查偏移量的合法性。
            throw new StringIndexOutOfBoundsException(offset);
        if (str == null)
            str = "null";//如果字符串为空,则将null字符串赋值给它。
        int len = str.length();
        ensureCapacityInternal(count + len);//确保足够的容量。
        System.arraycopy(value, offset, value, offset + len, count - offset);
        //把 offset 后面的字符串复制到 offset+len 位置。
        str.getChars(value, offset);//将字符串放到 offset 后,直接覆盖掉后面的若干字符。
        count += len;//更新 count。
        return this;//返回 this
    }

 

你可能感兴趣的:(Stringbuilder,面向对象)