在java中使用StringBuffer时,我想知道在需要重新分配空间时如何实现append函数。
例如,如果我追加一个比当前分配的空格更长的字符串,它如何在方法的细节中管理它?
答案 0 :(得分:5)
源代码包含在JDK下载中。只需查找src.zip文件(我的是Program Files(x86)\ Java \ jdk1.6.0_01 \ src.zip)。解压后,只需转到java / lang,就可以检查StringBuffer.java,StringBuilder.java和AbstractStringBuilder.java。
在此实现中,AbstractStringBuilder中的“expandCapacity”看起来像计算容量并执行Arrays.copyOf()来扩展缓冲区。值得注意的是,第一次检查是针对< 0以防止溢出情况。
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);
}
答案 1 :(得分:4)
Apache Harmony实施依赖于AbstractStringBuilder
中的方法来管理添加/删除(StringBuffer extends AbstractStringBuilder
)。
AbstractStringBuilder
保留一个字符缓冲区(即char
s的数组)来保存当前的“字符串”。将任何对象的下一个字符串表示附加到此缓冲区时,它会检查缓冲区是否包含足够的空间,如果空间不足,则会分配新的字符缓冲区,复制旧缓冲区,然后将新字符串添加到该缓冲区。我们可以从enlargeBuffer
:
private void enlargeBuffer(int min) {
int newSize = ((value.length >> 1) + value.length) + 2;
char[] newData = new char[min > newSize ? min : newSize];
System.arraycopy(value, 0, newData, 0, count);
value = newData;
shared = false;
}
...当超出value
(保存char缓冲区的私有成员)的容量时,在任何append方法中调用此方法:
final void append0(char chars[]) {
int newSize = count + chars.length;
if (newSize > value.length) {
enlargeBuffer(newSize);
}
System.arraycopy(chars, 0, value, count, chars.length);
count = newSize;
}
标准的OpenJDK实现非常相似。同样,StringBuffer依赖于AbstractStringBuilder:
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);
}
请注意Arrays.copyOf
复制字符数组value
用空字符填充它,使其总大小为newCapacity
,这基本上等同于和声方法中的new char[...]
调用。同样,当没有足够的空间来添加下一个字符串段时,会调用expandCapacity
方法:
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;
}