一、AbstractStringBuilder类
这个抽象类是StringBuilder和StringBuffer的直接父类,而且定义了很多方法,因此在学习这两个类之间建议先学习 AbstractStringBuilder抽象类
该类在源码中注释是以JDK1.5开始作为前两个类的父类存在的,可是直到JDK1.8的API中,关于StringBuilder和StringBuffer的父类还是Object
abstract class AbstractStringBuilder implements Appendable, CharSequence
实现了两个接口,其中CharSequence这个字符序列的接口已经很熟悉了:
该接口规定了需要实现该字符序列的长度:length();
可以取得下标为index的的字符:charAt(int index);
可以得到该字符序列的一个子字符序列: subSequence(int start, int end);
规定了该字符序列的String版本(重写了父类Object的toString()):toString();
Appendable接口顾名思义,定义添加的’规则’:
append(CharSequence csq) throws IOException:如何添加一个字符序列
append(CharSequence csq, int start, int end) throws IOException:如何添加一个字符序列的一部分
append(char c) throws IOException:如何添加一个字符
二、AbstractStringBuilder属性
//该字符序列的具体存储
char value[];
//实际存储的数量
int count;
注意:(和String中的value和count不同,String中的这两者都是不可变的(final修饰),并且不能对value[]直接操作;而AbstractStringBuilder的两者都是可变的,并且也定义了getValues方法让我们可以直接拿到value[],value实际上是个动态数组,和ArrayList的实现有很多相似的地方)
三、AbstractStringBuilder构造方法
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
四、AbstractStringBuilder常用方法
public int length()
public int length() {
return count;
}
public int capacity()
public int capacity() {
return value.length;
}
public void ensureCapacity(int minimumCapacity)
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
void expandCapacity(int minimumCapacity)
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
扩容的算法:
如果调用了该函数,说明容量不够用了,先将当前容量+1的二倍(newCapacity)与需要的容量(minimumCapacity)比较。
如果比需要的容量大,那就将容量扩大到容量+1的二倍;如果比需要的容量小,那就直接扩大到需要的容量。
使用Arrays.copyOf()这个非常熟悉的方法来使数组容量动态扩大
public void trimToSize()
public void trimToSize() {
if (count < value.length) {
value = Arrays.copyOf(value, count);
}
}
public void setLength(int newLength)
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);
if (count < newLength) {
for (; count < newLength; count++)
value[count] = '\0';
} else {
count = newLength;
}
}
charAt(int index)
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
getChars(int srcBegin, int srcEnd, char dst[],int dstBegin)
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);
}
public String substring(int start)
public String substring(int start) {
return substring(start, count);
}
public String substring(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
throw new StringIndexOutOfBoundsException(end);
if (start > end)
throw new StringIndexOutOfBoundsException(end - start);
return new String(value, start, end - start);
}
public CharSequence subSequence
public CharSequence subSequence(int start, int end) {
return substring(start, end);
}
public AbstractStringBuilder reverse()
public AbstractStringBuilder reverse() {
boolean hasSurrogate = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; --j) {
char temp = value[j];
char temp2 = value[n - j];
if (!hasSurrogate) {
hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
|| (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
}
value[j] = temp2;
value[n - j] = temp;
}
if (hasSurrogate) {
// Reverse back all valid surrogate pairs
for (int i = 0; i < count - 1; i++) {
char c2 = value[i];
if (Character.isLowSurrogate(c2)) {
char c1 = value[i + 1];
if (Character.isHighSurrogate(c1)) {
value[i++] = c1;
value[i] = c2;
}
}
}
}
return this;
}
public abstract String toString();
唯一的一个抽象方法
final char[] getValue() { return value; }
唯一的一个final方法:,得到value数组。可以对其直接操作
public AbstractStringBuilder replace(int start, int end, String str)
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);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start);
count = newCount;
return this;
}
添加的方法有很多,在此不过多解释
public AbstractStringBuilder append(Object obj)
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public AbstractStringBuilder delete(int start, int end)
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;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this;
}
public AbstractStringBuilder deleteCharAt(int index)
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
System.arraycopy(value, index+1, value, index, count-index-1);
count--;
return this;
}
public int indexOf(String str)
public int indexOf(String str) {
return indexOf(str, 0);
}
public int indexOf(String str, int fromIndex) {
return String.indexOf(value, 0, count,
str.toCharArray(), 0, str.length(), fromIndex);
}