2010-07-06 4 views
13

Я заметил, что метод возвращает capacityStringBuilder емкости без логики пути ... когда-то его значение равняется длиной строки другого времени это больше ...емкость StringBuilder()

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

+0

Почему вас беспокоит «емкость»? Он автоматически растет, чтобы разместить все, что необходимо. Вы можете играть с ним для повышения производительности, но она по-прежнему асимптотически линейна. – polygenelubricants

+5

В экзамене OCA есть вопросы о 'capacity' vs.' length', поэтому для некоторых людей проблема очень важна. –

ответ

3

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

String Builder must read

+0

+1 для хорошей ссылки – codebox

1

EDIT: Извинения - ниже приводится информация о StringBuilder .NET, а не строго относятся к первоначальному вопросу.

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

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

+0

Эта статья о C#, не так ли? –

+0

Да. Формула похожа на Java, но не совсем то же самое. – Catchwa

+1

Мои извинения - я видел StringBuilder и предполагал .NET. –

12

Когда вы добавляете к StringBuilder, следующая логика бывает:

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

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

expandCapacity просто увеличивает размер подложки char[]

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

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

  • Аргумент minimumCapacity.
  • Дважды старая емкость, плюс 2.

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

+1

Да, но если у меня есть: StringBuilder str = new StringBuilder(); // Вместимость 16 ул.добавление ("1111111111111111111"); емкость 32 длина 19 В соответствии с уравнением, почему мощность не равна 16 * 2 + 2 = 34 ?? – xdevel2000

1

Из 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

В источник JDK 7 нет больше + 2 символов только новое значение * 2 !!! – xdevel2000

+0

Интересно! Может быть, они выбрали это как оптимизацию? – Catchwa

+0

Возможно, однако, в документацию jdk 7, которая еще не обновлена! – xdevel2000

10

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

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

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

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

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

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

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

Этот анализ взять из actual StringBuilder.java code

0

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