AbstractString

来源:互联网 发布:windows安装清理工具 编辑:程序博客网 时间:2024/06/10 02:31

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;    }

数组反转的实现方式。

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