StringBuilder
StringBuilder
是可变字符串类型,它被人所熟知的功能就是可以很方便的对字符串进行拼接、构造:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
方法是 final
的,继承了 AbstractStringBuilder
抽象类:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
...
}
可以看到它实现了 Appendable
接口,而 Appendable
接口就是提供了可以被添加char序列和值的功能,它实现了三种 append
方法:
Appendable append(CharSequence csq) throws IOException;
Appendable append(CharSequence csq, int start, int end) throws IOException;
Appendable append(char c) throws IOException;
其中 CharSequence
是 char
值的可读序列,此接口对许多不同种类的 char
序列提供统一的只读访问, String
StringBuilder
StringBuffer
都实现了这个接口:
int length();
char charAt(int index);
CharSequence subSequence(int start, int end);
在 AbstractStringBuilder
抽象类中,提供了一系列的 append
和 insert
方法的实现,下面是其中一种实现:
public AbstractStringBuilder append(String str) {
if (str == null) str = "null"; //如果为空,则添加null字符串
int len = str.length();
ensureCapacityInternal(count + len);//保证容量
//复制str字符串到char数组value,从count位开始添加
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
如果传递的最小容量大于现有容量,则必须进行扩容:
void expandCapacity(int minimumCapacity) {
//新容量为old*2+2
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 = Arrays.copyOf(value, newCapacity);
}
注意: AbstractStringBuilder
中的方法实现都没有进行同步insert
方法:
public AbstractStringBuilder insert(int offset, String str) {
if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset);
if (str == null)
str = "null";
int len = str.length();
ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset);
count += len;
return this;
}
StringBuffer
StringBuffe
r类的出现实际上比 StringBuilder
要早,当初提供 StringBuilder
类只是为了提供一个单个线程使用的 StringBuffer
等价类。如果观察 StringBuffer
的源代码,可以发现它的方法和 StringBuilder
相同,只不过都加上了 synchronized
,比如:
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
StringBuilder vs StringBuffer
现在我们已经明确的记住了
StringBuffer
是线程安全的,而StringBuilder
不是在效率上,
StringBuffer
因为对方法做了同步,所以一般是低于StringBuilder
的二者都是可变的,因为二者都继承
AbstractStringBuilder
,它的char[] value
没有使用final
修饰,只是普通数组。String
的value
是final
的,即不可变的都有实现
CharSequence
接口