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;
}
数组反转的实现方式。
其中跳过了一部分方法,后续学习。