StringBuilder
介绍
StringBuilder 是一个线程不安全的字符串拼接类
使用
1. 构造StringBuilder对象
2.通过append方法来拼接字符串
StringBuilder stringBuilder = new StringBuilder(capacity);
stringBuilder.append(str).toString();
分析

StringBuilder 的实现基本都使用父类(AbstractStringBuilder)的方法。
1. 通过构造函数初始化一个capacity长度的字符数组 , 可以在构造函数中(1)指定capacity的值, 或者(2)传入字符串的长度,或者使用(3)默认值(16), ChatSequence对象的长度, 这个时候value是一个有长度未赋值的字符数组。
(1)
public StringBuilder(int capacity) {
super(capacity);
}
(2)
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
(3)
//如果未填capacity, 默认capacity为16
public StringBuilder() {
super(16);
}
(4)
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
// 生成的字符数组作为StringBuilder的value属性进行维护
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
2. 使用append方法拼接
(1)
public AbstractStringBuilder append(StringBuffer sb) {
// 先判断append的值是否为null, 如果为null则输出null字符串
if (sb == null)
return appendNull();
int len = sb.length();
// 确保当前维护的字符数组容量够, 当不够的时候先创建一个新的字符数组, 然后把旧的字符数组copy到新的字符数组上。 char[] newChatArray = Arrays.copyOf(char[] original, int newLength),
ensureCapacityInternal(count + len);
// sb.getChars 做各种溢出检查,将count作为拷贝起始游标, 将新的字符串拷贝到字符数组中, System.arrayCopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin)。
sb.getChars(0, len, value, count);
// 刷新游标位置
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
// 如果当前的字符数组容量不满足要求, 计算capacity生成新的字符数组副本 。
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
// capacity的计算 旧字符串长度平方 + 2 生成的长度比最小要求的长度还小。 那么就用最小要求的长度来作为新的长度。 否则就用新生成的长度。
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
// 溢出检查
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
Arrays.copyOf是System.arraycopy的一层封装。 生成一个拷贝副本。
Arrays.copyOf(value,
newCapacity(minimumCapacity));
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
总结
1. 在容量不够的情况下生成新的字符数组副本
2. append的字符串通过System.arraycopy拷贝到StringBuilder维护的字符数组中。
所以在可以知道拼接长度的时候指定StringBuilder的capacity, 减少生成字符数组副本的开销。
3. StringBuilder和StringBuffer都继承了AbstractStringBuilder, 它们的append方法都复用了父类的append, StringBuffer比StringBuilder多了synchronized, 所以StringBuffer是线程安全的。
但是绝大多数情况下是用不到线程安全版本的, 这也是StringBuilder诞生并且被大量使用的原因。
posted on 2018-03-06 16:56 hackeryutu 阅读(62) 评论(0) 收藏 举报
浙公网安备 33010602011771号