Java StringBuffer добавить распределение - PullRequest
4 голосов
/ 21 октября 2010

При использовании StringBuffer в Java, мне интересно, как реализована функция добавления, когда ей нужно перераспределить пространство.

Например, если я добавляю строку длиннее, чем выделенное в настоящее время пространство, как он справляется с этим в деталях метода?

Ответы [ 2 ]

5 голосов
/ 21 октября 2010

Источник включен в загрузку JDK.Просто найдите файл src.zip (мой находится в Program Files (x86) \ Java \ jdk1.6.0_01 \ src.zip).После распаковки просто перейдите в java / lang и вы можете изучить StringBuffer.java, StringBuilder.java и AbstractStringBuilder.java.

В этой реализации выглядит как "expandCapacity" в AbstractStringBuilder вычисляет емкость и выполняет Arrays.copyOf () для расширения буфера.Также интересно отметить, что первая проверка для <0 для защиты от переполнения. </p>

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);
}
4 голосов
/ 21 октября 2010

Реализация 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;
}
...