UML类图:
1.StringBuilder源码分析
public final class StringBuilder extends AbstractStringBuilder{},他继承一个抽象类,AbstractStringBuilder,抽象类声明他的两个属性:
char[] value;//具体数据
int count;//被使用的长度
自己动手写一个
public class MyStringBuilder {
char[] value;
int count;
MyStringBuilder(int capacity) {
value = new char[capacity];
}
public MyStringBuilder append(String str) {
int len = str.length();
ensureCapacityInternal(count + len);
// 这行的意思是将str的数据copy到原字符数组的后面,例如,value=['a','b','c',null,null,null,null],str="d",那么经过运算会得到value=['a','b','c','d','null','null']
str.getChars(0, len, value, count);
count += len;
return this;
}
@Override
public String toString() {
// 创建这个副本,底层还是使用到了system的arraycopy方法
return new String(value, 0, count);
}
/**
* 确保数组长度够
*
* @param minimumCapacity
*/
private void ensureCapacityInternal(int minimumCapacity) {
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
/**
* 扩容,拓展的数量为原长度*2+2
*
* @param minimumCapacity
*/
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
// 这行的意思是扩容,将value的长度增加,把原来的字符数组复制到新的数组
value = Arrays.copyOf(value, newCapacity);
}
}
测试方法:
public static void main(String[] args) {
MyStringBuilder sb = new MyStringBuilder(16);
sb.append("sniper ").append("我爱你");
System.out.println(sb.toString());
}
其实重要的方法其实就一个,就是System.arraycopy(),其他都是浮云;
2.StringBuffer源码分析
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
他和StringBuffer其实就是一模一样,唯一不一样的就是他是线程安全的,他的每个append方法都带了synchronized关键字,这也是为啥平时我们很少用他的原因,因为我们平时写代码不会把重要数据存到StringBuffer里面吧,那锁住他其实没必要。