Реализация Apache Harmony использует методы из AbstractStringBuilder
для управления добавлениями / удалениями ( StringBuffer extends AbstractStringBuilder
).
AbstractStringBuilder
keepсимвольный буфер (то есть массив 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
(закрытый член, который содержит буфер символов)будет превышено:
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;
}