AbstractString

AbstractStringBuilder是Stringbuffer和StringBuilder的夫类,这个类基本上实现了所有的功能,除了toString方法。该类实现了CharSequence和Appendable接口,就先送这两个接口开始开始吧。

CharSequence

该接口定义的是插入序列的可读访问,顾名思义,该接口的实现类的数据结构应该是有char[]实现的,通过该接口,我们可以访问
该其中的数据。方法有length,charAt,subSequent,toString。

Appendable

CharSequence只提供了访问的功能,该接口提供了append的功能。

以上两个接口主要描述了AbstractStringBuilder实现的方式和基本的访问,append功能。

具体实现:

属相:

data(char[]), count(int)

AbstractStringBuilder所有的功能基本就是通过这两个属性来实现的。data是一个char数组,count具体元素的大小,也是具体元素在数组中的标记,很多容器类都是通过这种方式来实现的。

构造器:

AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
生成一个char数组,此时没事添加元素,count为默认值0。
之前看了一些容器的实现方式,一般顺序是先看夫类,实现的接口,从上往下看,先了解夫类的特点和能力,往下扩散,这也是一般代码的实现方式,越上层越具体,越往下越抽象,也比较便于了解和接受。一般来说夫类中的抽象方法,是最基本的方法,如add,remove方法,而其他很多方法,都是在此基础之上去实现的。

方法:

该类相对比较简单,记录一下比较有趣的一些方法吧。
AbstractStringBuilder append(AbstractStringBuilder asb) {
        if (asb == null)
            return appendNull();
        int len = asb.length();
        ensureCapacityInternal(count + len);
        asb.getChars(0, len, value, count);
        count += len;
        return this;
    }
 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
    {
        if (srcBegin < 0)
            throw new StringIndexOutOfBoundsException(srcBegin);
        if ((srcEnd < 0) || (srcEnd > count))
            throw new StringIndexOutOfBoundsException(srcEnd);
        if (srcBegin > srcEnd)
            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

这两个 方法需要一起看,而关键是下面这行代码
 System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);

从这行代码可以看出getChars方法是把本对象的char[]拷贝到dst中。通过方法名看不出特点,这个是关键。

public AbstractStringBuilder insert(int offset, String str) {
        if ((offset < 0) || (offset > length()))
            throw new StringIndexOutOfBoundsException(offset);
        if (str == null)
            str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);
        System.arraycopy(value, offset, value, offset + len, count - offset);//1
        str.getChars(value, offset);//2
        count += len;
        return this;
    }

这个方法分两步:

第一步:

如果原数组组为[0,1,2,3,4,5,6,7,8],str为"999",,offset为1

则通过这一步,数组变为

[0,1,2,3,1,2,3,4,5,6,7,8]

目的在原数组中,为要插入的字符创腾出位置。

第二步:

void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }

  此方法为String类的方法,所以这里的value是[9,9,9],dst为[0,1,2,3,1,2,3,4,5,6,7,8]。上述方法主要是要搞明白每个方法里面的value到底是哪个对象的value,看清楚调用getChars是参数调用的就可以了。


public AbstractStringBuilder reverse() {
        boolean hasSurrogates = false;
        int n = count - 1;
        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;
            if (Character.isSurrogate(cj) ||
                Character.isSurrogate(ck)) {
                hasSurrogates = true;
            }
        }
        if (hasSurrogates) {
            reverseAllValidSurrogatePairs();
        }
        return this;
    }

数组反转的实现方式。

其中跳过了一部分方法,后续学习。


      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值