Емкость StringBuilder () - PullRequest
       18

Емкость StringBuilder ()

15 голосов
/ 06 июля 2010

Я заметил, что метод capacity возвращает емкость StringBuilder без логического пути ... иногда его значение равно длине строки, в противном случае он больше ...

есть уравнение длязнаете, в чем его логика?

Ответы [ 7 ]

13 голосов
/ 06 июля 2010

При добавлении к StringBuilder происходит следующая логика:

if (newCount > value.length) {
    expandCapacity(newCount);
}

, где newCount - это количество необходимых символов, а value.length - текущий размер буфера.

expandCapacity просто увеличивает размер основы char[]

Метод ensureCapacity() является общедоступным способом вызова expandCapacity(), и его документы говорят:

Гарантирует, что емкость как минимум равна указанному минимуму.Если текущая емкость меньше аргумента, то выделяется новый внутренний массив с большей емкостью.Новая емкость больше:

  • Аргумент минимальной емкости.
  • Вдвое больше старой емкости плюс 2.

Если аргумент минимальной емкости неположителенэтот метод не предпринимает никаких действий и просто возвращает.

11 голосов
/ 10 декабря 2013

Я попытаюсь объяснить это на каком-то примере.

public class StringBuilderDemo {
     public static void main(String[] args) {
         StringBuilder sb = new StringBuilder();
         System.out.println(sb.length());
         System.out.println(sb.capacity());
     }
}

length() - длина последовательности символов в компоновщике, поскольку этот компоновщик строк не содержит никакого содержимого, его длина будет 0.

capacity() - количество выделенных символьных пространств.Когда вы пытаетесь создать string Builder с пустым содержимым, по умолчанию он принимает размер инициализации как длину + 16, которая равна 0 + 16.в этом случае емкость будет возвращаться 16.

Примечание. Емкость, возвращаемая методомacity (), всегда больше или равна длине (обычно больше) и будет автоматически расширяться по мере необходимости.дополнения к компоновщику строк.

Логика функции емкости:

  1. Если вы не инициализируете компоновщик строк с каким-либо содержимым, будет использована емкость по умолчанию.емкостью 16 символов.
  2. Если вы инициализируете stringbuilder с любым содержимым, то емкость будет иметь длину содержимого + 16.
  3. При добавлении нового содержимого в объект stringbuilder, если текущей емкости недостаточно дляпринять новое значение, тогда оно будет расти на (предыдущая емкость массива + 1) * 2.

Этот анализ взят из фактического кода StringBuilder.java

4 голосов
/ 06 июля 2010

Эта функция делает что-то не то, что вы ожидаете - она ​​дает вам максимальное количество символов, которое эта память StringBuilder может хранить в это время

Строитель строк должен читать

1 голос
/ 16 марта 2018

Вот логика: если вы определяете новый экземпляр класса StringBuilder без конструктора, например new StringBuilder();, емкость по умолчанию равна 16. Конструктор может быть либо int, либо String.Для конструктора String емкость по умолчанию рассчитывается так* добавляется к StringBuilder и новая длина String больше текущей емкости, тогда емкость рассчитывается следующим образом:

int newCapacity = (oldCapacity + 1) * 2;
1 голос
/ 06 июля 2010

Из API:

У каждого строителя строк есть емкость.Пока длина символьной последовательности, содержащейся в построителе строк, не превышает емкости, нет необходимости выделять новый внутренний буфер.Если внутренний буфер переполняется, он автоматически увеличивается.

Когда вы добавляете что-то, есть проверка, чтобы убедиться, что обновленный StringBuilder не превысил свою емкость, и если это так, тоРазмер внутреннего хранилища StringBuilder изменяется:

int len = str.length();
int newCount = count + len;
if (newCount > value.length)
  expandCapacity(newCount);

Когда к нему добавляются данные, размер которых превышает его емкость, он изменяется по следующей формуле:

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);
}

См. src.zip файл, который поставляется с JDK для получения дополнительной информации.(Выше фрагменты взяты из 1.6 JDK)

1 голос
/ 06 июля 2010

РЕДАКТИРОВАТЬ: Извинения - ниже приведена информация о .NET StringBuilder, и не имеет прямого отношения к первоначальному вопросу.

http://johnnycoder.com/blog/2009/01/05/stringbuilder-required-capacity-algorithm/

StringBuilder выделяет пространство для подстрок, которые вы можете добавить к нему (подобно тому, как List создает пространство в массиве, который он оборачивает). Если вы хотите фактическую длину строки, используйте StringBuilder.Length.

0 голосов
/ 09 декабря 2015

Вы можете зайти внутрь кода JDK и посмотреть, как он работает, он основан на массиве символов: new char[capacity], он похож на то, как работает ArrayList ( Когда использовать LinkedList поверх ArrayList? ).Оба используют массивы, чтобы быть «аппаратно-эффективными», трюк состоит в том, чтобы выделить большой кусок памяти и работать в нем, пока у вас не закончится память и вам не понадобится следующий большой блок для продолжения (расширения / роста).

...