区别
StringBuffer:jdk 1.0出现,线程安全,效率低
StringBuilder: jdk 1.5出现,线程不安全,效率高
StringBuilder怎么实现的线程安全
StringBuilder 中的大量方法都使用 synchronized 修饰,来实现线程安全,就是因为这样速度才会慢。
二者的实现几乎没什么区别,具有相同的父类和接口,具体实现方法都由父类完成。
StringBuffer 部分源码
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
// toString返回的最后一个值的缓存。每当修改StringBuffer时清除。
private transient char[] toStringCache;
// 默认初始化容量为16个字符
public StringBuffer() {
super(16);
}
// 如果构造方法中传入了一个字符串,长度为字符串长度加16
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
// 被 synchronized 修饰方法还有很多,不再一一列举
@Override
public synchronized StringBuffer append(String str) {
// StringBuffer将会被修改,清除 toStringCache
toStringCache = null;
super.append(str);
return this;
}
// 重写toString方法
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
}
StringBuilder 部分源码
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
// 默认初始化容量为16个字符
public StringBuilder() {
super(16);
}
// 如果构造方法中传入了一个字符串,长度为字符串长度加16
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
// 添加字符串方法
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
// toString 方法
@Override
public String toString() {
// 创建一个副本,不要共享数组
return new String(value, 0, count);
}
}
扩容方法
先扩充为 原长度 * 2 + 2 的长度,然后判断扩充后的长度是否大于StringBuilder拼接字符串后的长度(新添加的+已有的长度),如果小于的话,就执行
newCapacity = StringBuilder
(StringBuilder为拼接后字符串的长度)。如果newCapacity<0
说明数组长度已经超出了范围,这时调用hugeCapacity方法,执行newCapacity = Integer.MAX_VALUE
。
AbstractStringBuilder 部分源码
// 用于字符存储。
char[] value;
// 数组最大长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
// 扩容方法
private int newCapacity(int minCapacity) {
// 先扩充为 原长度 * 2 + 2 的长度
int newCapacity = (value.length << 1) + 2;
// 判断扩充后的长度是否大于StringBuilder拼接字符串后的长度
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
// 数组再次扩容,但是长度不能超出int范围
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
网友评论