实现原理
1. 创建实例
StringBuilder实例被创建时,有一定容量的char[]被创建。
public StringBuilder() {
super(16);
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
2. append
首先判断char[]容量是否足够,不够则进行扩容,然后将数据拷贝到char[]中,如下所示:
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
3. toString
创建新的char[]将数据拷贝进去
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
存在问题
- 空间和时间效率不高;
- 线程不安全;
优化建议
1. 设置合理的初始长度
避免频繁的扩容和数据迁移,如果不好精确预估,可以适当预估大些。
2. 复用StringBuilder
JDK内置的BigDecimal采用这种策略,实现如下:
public class StringBuilderHolder {
private final StringBuilder sb;
public StringBuilderHolder(int capacity) {
sb = new StringBuilder(capacity);
}
public StringBuilder resetAndGet() {
sb.setLength(0);
return sb;
}
}
private static final ThreadLocal<StringBuilderHolder> stringBuilder= new ThreadLocal<StringBuilderHolder>() {
@Override
protected StringBuilderHolder initialValue() {
return new StringBuilderHolder(256);
}
};
参考: