一、背景
1.关于AbstractStringBuilder是一个抽象实现类,所以不能直接new对象,接下来主要分析他的子类StringBuilder,来看下它底层主要是实现了什么把数据加上。
2.今天主要介绍的是StringBuilder类中的其他源码的方法分析,接下来我们来看看源码吧。
3.关于AbstractStringBuilder的源码的解析,可以参照我上篇文章的分析,地址:https://blog.csdn.net/chenmingxu438521/article/details/100571990
二、源码分析之appendCodePoint(int i)方法
1.其实这个方法说白了就是把添加的数字变成ascll码值,下面我们来看下具体的源码实现。
public StringBuilder appendCodePoint(int codePoint) {
super.appendCodePoint(codePoint);
return this;
}
2.看下父类中怎么实现的AbstractStringBuilder中的appedCodePoint(int codePoint)
public AbstractStringBuilder appendCodePoint(int codePoint) {
//之前添加的数据的长度,没有的话默认为0 codePoint为67 结果为JAVAC,C为67的ascll码值
final int count = this.count;
//要添加的codePoint>>>16,此时为true
if (Character.isBmpCodePoint(codePoint)) {
//看是否要进行扩容
ensureCapacityInternal(count + 1);
//把要添加的codePoint变成字节赋值给之前的赋值好的字节数组后面
value[count] = (char) codePoint;
//返回数据的长度
this.count = count + 1;
} else if (Character.isValidCodePoint(codePoint)) {
ensureCapacityInternal(count + 2);
Character.toSurrogates(codePoint, value, count);
this.count = count + 2;
} else {
throw new IllegalArgumentException();
}
return this;
}
3.ensureCapacityInternal(count+1)方法
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
//具体扩容是在newCapacity()中进行的
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
三、源码分析之insert(int index,char[] str,int offset,int len)方法
1.先看 个小例子
StringBuilder sb = new StringBuilder();
sb.append("JAVA");
sb.insert(1,"LOVE",1,2);
System.out.println(sb);
1.1.结果
JOAVA
1.2.分析
insert(int index,char[] str,int offset,int len),第一个参数就是LOVE中的O,后面的1和2参数代表的是之前已经添加的JAVA的位置进行添加,包左不包右。所以结果就是JOAVA。
2.具体的源码分析
public StringBuilder insert(int dstOffset, CharSequence s,int start, int end){
super.insert(dstOffset, s, start, end);
return this;
}
3.看下父类中怎么实现的AbstractStringBuilder中的insert(int index,char[] str,int offset,int len)方法。
public AbstractStringBuilder insert(int dstOffset, CharSequence s,int start, int end) {
if (s == null)
s = "null";
if ((dstOffset < 0) || (dstOffset > this.length()))
throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
throw new IndexOutOfBoundsException("start " + start + ", end " + end + ", s.length() "+ s.length());
int len = end - start;
//看否要进行扩容
ensureCapacityInternal(count + len);
//dstOffset是起始偏移量,dstOffset是结束偏移量,长度的偏移量是count-dstOffset,就是复制到一个新数组中
System.arraycopy(value, dstOffset, value, dstOffset + len,count - dstOffset);
for (int i=start; i<end; i++)
//循环把要替换的值赋值给原来的值的对应的位置
value[dstOffset++] = s.charAt(i);
//原来的值长度加上要赋值的长度
count += len;
return this;
}
4.其他的insert()方法类似就不详细分析了
四、源码分析之delete(int start,int end)方法
1.具体的源码分析
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
2.看下父类中怎么实现的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;
}
五、源码分析之replace()方法
1.具体的源码分析
public StringBuilder replace(int start, int end, String str) {
super.replace(start, end, str);
return this;
}
2.看下父类中怎么实现的AbstractStringBuilder中的replace()方法。
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);
ensureCapacityInternal(newCount);
System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start);
count = newCount;
return this;
}
3.具体看下getChars()方法
void getChars(char dst[], int dstBegin) {
//这一步具体的替换
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
六、结束
其他的有兴趣的可以自己去研究下!!!