您的位置:首页 > 产品设计 > UI/UE

StringBuilder和StringBuffer源码浅析

2016-05-13 00:53 519 查看
首先我们来看两个类的继承体系:

public final class StringBuilder extends AbstractStringBuilder implements
Appendable, CharSequence, Serializable;

public final class StringBuffer extends AbstractStringBuilder implements
Appendable, Serializable, CharSequence


二者基本类似,我们看AbstravtStringBuilder这个类

private char[] value;
static final int INITIAL_CAPACITY = 16;
AbstractStringBuilder() {
value = new char[INITIAL_CAPACITY];
}

AbstractStringBuilder(int capacity) {
if (capacity < 0) {
throw new NegativeArraySizeException(Integer.toString(capacity));
}
value = new char[capacity];
}
AbstractStringBuilder(String string) {
count = string.length();
shared = false;
value = new char[count + INITIAL_CAPACITY];
string.getCharsNoCheck(0, count, value, 0);
}


默认初始容量为16,当然我们也可以自己设置容量大小;接着我们看看拼接过程

final void append0(char[] chars) {
int newCount = count + chars.length;
if (newCount > value.length) {
enlargeBuffer(newCount);
}
System.arraycopy(chars, 0, value, count, chars.length);
count = newCount;
}


enlargeBuffer(newCount);即为扩容方法;

接下来我们看看扩容过程,

首先是确定容量过程

~~   public void ensureCapacity(int min) {
if (min > value.length) {
int ourMin = value.length*2 + 2;
enlargeBuffer(Math.max(ourMin, min));
}
}~~


如果需要扩展的最小容量大于当前长度,则取原来容量的两倍+2,然后比较该值与所需最小容量,取二者最大值

private void enlargeBuffer(int min) {
int newCount = ((value.length >> 1) + value.length) + 2;
char[] newData = new char[min > newCount ? min : newCount];
System.arraycopy(value, 0, newData, 0, count);
value = newData;
shared = false;
}


然后我们会看到上一步中的最大值会接着和原来容量*1.5+2比较,并取二者最大值(也就是说在所需容量大于原来容量的情况下,比较扩展所需的容量和2 *value.length+2,1.5 *value.length+2并取三者最大值作为新数组容量)。所以我们在创建SB的时候,可以估算新字符串的长度来适当避免多次扩容,影响效率。

接着我们来看看StringBuffer的append方法

public synchronized StringBuffer append(char[] chars) {
append0(chars);
return this;
}


和StringBuilder的append方法

`

public StringBuilder append(char c) {

append0(c);

return this;

}


这就是一个线程安全而另一个线程不安全的原因`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: