jdk源码解读-AbstractStringBuilder

类定义

abstract class AbstractStringBuilder implements Appendable, CharSequence {}

抽象类,是StringBuffer和StringBuilder的父类,实现了两个接口:

  1. CharSequence

    a. 该接口规定了需要实现该字符序列的长度:length();
    b. 可以取得下标为index的的字符:charAt(int index);
    c. 可以得到该字符序列的一个子字符序列: subSequence(int start, int end);

  2. Appendable

    这个接口有3个方法,都是append添加字符或字符序列的

    a. append(CharSequence csq) :如何添加一个字符序列

    b. append(CharSequence csq, int start, int end) :如何添加一个字符序列的一部分

    c. append(char c) :如何添加一个字符

成员变量

  1. char[] value; 该字符序列的具体存储

  2. int count; 实际存储的数量,注意和capacity的区别,count是value中实际存了数据的长度,capacity是value的总长度,也就是value.length
    在这里插入图片描述
    还需要注意的是,value和count都不是final修饰的,是可变的,也就是修改和扩容,修改就是修改这个char数组的某个值,而扩容并非真的扩容,扩容是通过调用Arrays.copyOf来实现的,而Arrays.copyOf其实是new了一个新的数组来实现的

    public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength]; //新建了一个数组
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

构造方法

   AbstractStringBuilder() {
    }

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

重要知识点

length和capacity两个char数组指针

length方法返回的是value当前实际使用的数量,capacity返回的是value的总长度

    @Override
    public int length() {
        return count;
    }

    public int capacity() {
        return value.length;
    }

扩容

ensureCapacity提供了判断char数组容量加上需要增加的容量是否大雨数组最大边界,expandCapacity是AbstractStringBuilder实现扩容的方法。扩容的大小是 (capacity+1)乘以2,如果(capacity+1)*2 小于传入的参数(所需的容量大小),直接用所需的容量大小作为capacity。扩容的方式是通过用Arrays.copyOf来进行数组拷贝。

    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2; //先计算原来(value.length(也就是capacity)+1)*2
        if (newCapacity - minimumCapacity < 0)
            //如果计算后的newCapacity还是比传入的值小,直接用传入的值作为新的capacity
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            //进行了溢出判断,防止出现原来数组的(capacity+1)*2>65535的情况,如果出现了直接将65535作为新的capacity
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        //用Arrays.copyOf来进行数组拷贝,看Arrays源码可知,其实是new了一个新的数组
        value = Arrays.copyOf(value, newCapacity);
    }

getValue

不同与String无法获取value,AbstractStringBuilder提供了直接获取value进行操作的方法。

append

append是最重要的方式。细看源码,主要可以分为两种append方式

  1. System.arraycopy的方式

    例如String、Stringbuffer、int、float、long等都是通过XX.getChars的方法来追加,但getChars方法底层源码都还是采用System.arraycopy实现的。

        public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }
    

    str.getChars(0, len, value, count);,这句代码是append追加的关键,是通过String的getChars方法将,str字符串的char字符数组,从0到len复制(源码中使用了System.arraycopy)给AbstractStringBuilder的value,并从value的count位置起追加复制

    char数组是直接调用System.arraycopy实现追加的

    Object会先调用String.valueOf方法,然后再调用上面的传入参数为String的append重载方法。也因此,当Object为null时,String.valueOf返回的字符串为“null”

        public AbstractStringBuilder append(Object obj) {
            return append(String.valueOf(obj));
        }
    
  2. 在原来的value后面赋值的方式

    例如appendNull、appendBoolean、appendChar,都是直接给value后面还没有使用的索引赋值的

        private AbstractStringBuilder appendNull() {
            int c = count;
            ensureCapacityInternal(c + 4);
            final char[] value = this.value;
            value[c++] = 'n';
            value[c++] = 'u';
            value[c++] = 'l';
            value[c++] = 'l';
            count = c;
            return this;
        }
    

hashcode和equals

看了AbstractStringBuilder的源码,没有找到hashcode和equals这两个方法,所以这两个方法还是用的Object方法(与String不同)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值