StringBuffer和StringBuilder的区别是StringBuffer是线程安全的,StringBuilder则不是,所以当不考虑线程安全的时候,StringBuilder效率更高。
个人理解,水平不够,还请指正。
1、CharSequence
String实现了三个接口,其中一个是CharSequence,StringBuilder和StringBuffer也都实现了这个接口
CharSequence接口中有这些东西:
int length();//返回char序列的长度,即有多少个字符在这个序列中
char charAt(int index);//返回特定位置的字符,从0到length()-1
CharSequence subSequence(int start, int end);//返回子序列,从0到length()-1
public String toString();//返回与char序列同样字符顺序的String对象
有些函数就会以CharSequence作为参数,可以将String,StringBuffer,StringBuilder作为参数参入。
2、String StringBuffer的属性
1.1String属性
private final char value[];//用于字符存储,是final类型的
String str = "abc";
相当于
char data[] = {'a', 'b', 'c'};
String str = new String(data);
String的构造函数会初始化value数组,一旦初始化就不能改变了。
所以如果str = "def";只是改变了str的引用,变为"def"字符串的引用了。"abc"、"def"是两个堆区中的对象。
1.2StringBuffer属性
StringBuffer继承于AbstractStringBuilder
AbstractStringBuilder中的属性有
char[] value;
int count;
可以看到StringBuffer中的这里的value不是final的。
在任何时间点都有一个特有的字符序列,其长度和内容可以通过StringBuffer中的方法改变。
下面具体看看StringBuffer的方法。
length()得到是有多少个字符。
public int length() {
return count;
}
capacity()得到是value数组分配的长度
public int capacity() {
return value.length;
}
当新分配的容量比原来的capacity大时,会进行扩容
这个expandCapacity方法并没有进行大小检查和同步处理,其他方法在调用时需要先做判断
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
//这个地方的判断没看懂,什么情况下会<0
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
Arrays.copyOf(value, newCapacity)
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
System.arraycopy
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
最后通过System.arraycopy来进行数组扩充内容,因为这个函数是native的,效率比较高
未完。。