StringBuilder源码阅读

一.接口分析

    继承自AbstractStringBuilder;抽象类
   该抽象类提供了两个参数,如下:

/**
 * The value is used for character storage.
 * 和String一样用来保存char数组
 */
char[] value;

/**
 * The count is the number of characters used.
 * 被使用的char的长度、总数
 */
int count;

二.参数分析

三.方法分析

1.构造方法

构造方法会默认对加进来的数组加上16位的长度,并调用append方法对字符串进行构造,存入数组

2.append

append方法会直接调用父类的append进行操作,每一种类型的append操作都有一定差别,但是步骤差不多

  • String.getChars的操作,其实就是往目标数组中复制源数组的全部元素,但是这个方法如果目标数组长度不够会直接报错。
  • 所以在此之前加了一步char数组容量判断和扩容的操作来支撑
   public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        //1.确定char数组长度,如果不够的话就补长度
        ensureCapacityInternal(count + len);
        //2.这边是通过System.arraycopy的native方法复制数组元素
        str.getChars(0, len, value, count);
        //3.对使用的字符串该参数进行赋值
        count += len;
        return this;
    }
   
   private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
        }
    }


 /**
     * Copy characters from this string into dst starting at dstBegin.
     * This method doesn't perform any range checking.
     */
    void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }

3.delete

delete方法也是通过【下标的移动】确定需要复制的数组,下标移动到前后需要复制的位置

  public AbstractStringBuilder delete(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            end = count;
        if (start > end)
            throw new StringIndexOutOfBoundsException();
        int len = end - start;
        //1.如果计算要删除的长度大于0,这边从value的前面直到要被删除的位置位置+value后面减掉要被删除的位置结束 进行复制
        if (len > 0) {
            System.arraycopy(value, start+len, value, start, count-end);
            count -= len;
        }
        return this;
    }

删除过程如下:在这里插入图片描述

4.replace

  • 容量判断和扩容
  • 把没有被replace的后面的元素拼接到被替换的end位置后
  • 向数组中覆盖对应元素
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;
        int len = str.length();
        int newCount = count + len - (end - start);
        //1.判断数组容量和扩容操作
        ensureCapacityInternal(newCount);
        //2.将value中需要被替换的位置剔除掉.用后面下标的元素去覆盖
        System.arraycopy(value, end, value, start + len, count - end);
        //3.往剔除好的value中添加要被替换的char数组
        str.getChars(value, start);
        count = newCount;
        return this;
    }

两步操作,图示如下:
在这里插入图片描述

5.insert

insert就是给要插入的元素预留一个空间,然后再把这个元素插入进来

    public AbstractStringBuilder insert(int index, char[] str, int offset,
                                        int len)
    {
        if ((index < 0) || (index > length()))
            throw new StringIndexOutOfBoundsException(index);
        if ((offset < 0) || (len < 0) || (offset > str.length - len))
            throw new StringIndexOutOfBoundsException(
                "offset " + offset + ", len " + len + ", str.length "
                    + str.length);
        //1.长度判断和扩容
        ensureCapacityInternal(count + len);
        //2.value从要insert的位置,进行后面char[]的复制
        System.arraycopy(value, index, value, index + len, count - index);
        //3.再把要insert的char[]放到对应位置
        System.arraycopy(str, offset, value, index, len);
        count += len;
        return this;
    }

操作图示如下,按照序号:
在这里插入图片描述

6.reverse

    public AbstractStringBuilder reverse() {
        boolean hasSurrogates = false;
        int n = count - 1;
        //1.reverse方法比较简单,就是循环,然后交换前后位置的值
        for (int j = (n-1) >> 1; j >= 0; j--) {
            int k = n - j;
            char cj = value[j];
            char ck = value[k];
            value[j] = ck;
            value[k] = cj;
            //2.这边有一个好像是跟编码有关的,具体不知道做啥用.
            if (Character.isSurrogate(cj) ||
                Character.isSurrogate(ck)) {
                hasSurrogates = true;
            }
        }
        if (hasSurrogates) {
            reverseAllValidSurrogatePairs();
        }
        return this;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了-凡

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值