一.接口分析
继承自AbstractStringBuilder;抽象类
该抽象类提供了两个参数,如下:
/**
* The value is used for character storage.
* 和String一样用来保存char数组
*/
char[] value;
/**
* The count is the number of characters used.
* 被使用的char的长度、总数
*/
int count;
二.参数分析
无
三.方法分析
1.构造方法
构造方法会默认对加进来的数组加上16位的长度,并调用append方法对字符串进行构造,存入数组
2.append
append方法会直接调用父类的append进行操作,每一种类型的append操作都有一定差别,但是步骤差不多
- String.getChars的操作,其实就是往目标数组中复制源数组的全部元素,但是这个方法如果目标数组长度不够会直接报错。
- 所以在此之前加了一步char数组容量判断和扩容的操作来支撑
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
//1.确定char数组长度,如果不够的话就补长度
ensureCapacityInternal(count + len);
//2.这边是通过System.arraycopy的native方法复制数组元素
str.getChars(0, len, value, count);
//3.对使用的字符串该参数进行赋值
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
/**
* Copy characters from this string into dst starting at dstBegin.
* This method doesn't perform any range checking.
*/
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
3.delete
delete方法也是通过【下标的移动】确定需要复制的数组,下标移动到前后需要复制的位置
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;
//1.如果计算要删除的长度大于0,这边从value的前面直到要被删除的位置位置+value后面减掉要被删除的位置结束 进行复制
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this;
}
删除过程如下:
4.replace
- 容量判断和扩容
- 把没有被replace的后面的元素拼接到被替换的end位置后
- 向数组中覆盖对应元素
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);
//1.判断数组容量和扩容操作
ensureCapacityInternal(newCount);
//2.将value中需要被替换的位置剔除掉.用后面下标的元素去覆盖
System.arraycopy(value, end, value, start + len, count - end);
//3.往剔除好的value中添加要被替换的char数组
str.getChars(value, start);
count = newCount;
return this;
}
两步操作,图示如下:
5.insert
insert就是给要插入的元素预留一个空间,然后再把这个元素插入进来
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
{
if ((index < 0) || (index > length()))
throw new StringIndexOutOfBoundsException(index);
if ((offset < 0) || (len < 0) || (offset > str.length - len))
throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length "
+ str.length);
//1.长度判断和扩容
ensureCapacityInternal(count + len);
//2.value从要insert的位置,进行后面char[]的复制
System.arraycopy(value, index, value, index + len, count - index);
//3.再把要insert的char[]放到对应位置
System.arraycopy(str, offset, value, index, len);
count += len;
return this;
}
操作图示如下,按照序号:
6.reverse
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
//1.reverse方法比较简单,就是循环,然后交换前后位置的值
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;
//2.这边有一个好像是跟编码有关的,具体不知道做啥用.
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
}