StringBuffer/StringBuilder
- StringBuffer来自JDK 1.0,StringBuilder来自JDK 1.5。StringBuffer在1.5后被重构。两个类都基于1.5的AbstractStringBuilder。实现方式是一致的。StringBuffer的核心方法是线程安全的,使用了synchronized,StringBuilder则没有。
public final class StringBuffer extends AbstractStringBuilder
public final class StringBuilder extends AbstractStringBuilder
- 字符串使用char数组进行存储,默认的初始大小为16。如果使用已知的字符串初始化,则初始化大小为已知字符串长度+16。
/**
* The value is used for character storage.
*/
char value[];
/**
* The count is the number of characters used.
*/
int count;
public StringBuilder() {
super(16);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
- append方法,append当发现存储空间不足时,会依照(当前长度+1)*2的计算原则,扩展存储空间,扩展方法基于底层的本地方法System.arraycopy方法,实现新、老存储空间内的char数据的快速拷贝。实现方法依赖于jre的底层实现。扩展的最大存储空间为int长度(231-1),超过时,不会发生异常,会忽略后面的字符串信息。
public AbstractStringBuilder append(String str) {
if (str == null)
str = "null";
int len = str.length();
if (len == 0)
return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
str.getChars(0, len, value, count);
count = newCount;
return this;
}
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
- delete方法,使用System.arraycopy的移位操作,覆盖原有的char值,同时修正len。剩下的空闲位不会处理。
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start + len, value, start, count - end);
count -= len;
}
return this;
}
- toString方法,创建一个和当前StringBuffer/StringBuilder中值相同的字符串。
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}