2010-07-06 13 views
13

me di cuenta de que el método devuelve capacityStringBuilder capacidad sin una manera lógica ... en algún momento su valor es igual a la longitud de la cadena otra vez es mayor ...capacidad StringBuilder()

es que hay una ecuación para saber cuál es su lógica?

+0

¿Por qué te importa la 'capacidad'? Crece automáticamente para acomodar lo que sea necesario. Puedes jugar con él para mejorar el rendimiento, pero sigue siendo asintóticamente lineal. – polygenelubricants

+5

Hay preguntas acerca de la "capacidad" frente a la "longitud" en el examen OCA, por lo que para algunas personas el problema sí significa mucho. –

Respuesta

3

Esta función hace algo diferente a lo esperado: le ofrece el número máximo de caracteres que esta memoria de instancia de StringBuilder puede contener en este momento.

String Builder must read

+0

+1 para el bonito enlace – codebox

1

EDIT: Disculpas - el siguiente es información sobre StringBuilder de .NET, y no es estrictamente relevante a la pregunta original.

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

StringBuilder asigna espacio para subseries se puede agregar a él (al igual que crea un espacio Lista la matriz que envuelve). Si desea la longitud real de la cadena, use StringBuilder.Length.

+0

Este artículo es sobre C#, ¿no es así? –

+0

Sí. La fórmula es similar a Java pero no exactamente igual. – Catchwa

+1

Mis disculpas: vi StringBuilder y asumí .NET. –

12

Cuando anexa a la StringBuilder, la lógica siguiente sucede:

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

donde newCount es el número de caracteres necesarios, y value.length es el tamaño actual de la memoria intermedia.

expandCapacity simplemente aumenta el tamaño del respaldo char[]

El método ensureCapacity() es la vía pública para llamar expandCapacity(), y sus docs decir:

asegura que la capacidad es al menos igual a la especificada mínimo. Si la capacidad actual es menor que el argumento, se asigna una nueva matriz interna con mayor capacidad. La nueva capacidad es la más grande de:

  • El argumento de MinimumCapacity.
  • El doble de la capacidad de edad, además de 2.

Si el argumento minimumCapacity es no positivo, este método no toma ninguna acción y simplemente devuelve.

+1

sí, pero si tengo: StringBuilder str = new StringBuilder(); // capacidad 16 str.append ("1111111111111111111"); capacidad 32 longitud 19 Según la ecuación ¿por qué la capacidad no es 16 * 2 + 2 = 34? – xdevel2000

1

De la API:

Cada constructor de cadena tiene una capacidad. Siempre que la longitud de la secuencia de caracteres contenida en el generador de cadenas no exceda la capacidad, , no es necesario asignar un nuevo buffer interno . Si el búfer interno se desborda, se ampliará automáticamente .

Cada vez que usted adiciona algo, hay una comprobación para asegurarse de que el StringBuilder actualizada no será superior a su capacidad, y si lo hace, el almacenamiento interno del StringBuilder se cambia el tamaño:

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

cuando se añade datos en ella que excede su capacidad se re-dimensionado de acuerdo con la siguiente fórmula:

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

vea el archivo src.zip que viene con el JDK para más informati en. (Sobre los fragmentos tomados del 1.6 JDK)

+1

En la fuente JDK 7 no hay más + 2 caracteres solo el nuevo valor * 2 !!! – xdevel2000

+0

¡Interesante! Tal vez lo sacaron como una optimización? – Catchwa

+0

¡Quizás, sin embargo, en la documentación de jdk 7 que aún no está actualizada! – xdevel2000

10

Trataré de explicar esto con un ejemplo.

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

length() - la longitud de la secuencia de caracteres en el constructor ya que este StringBuilder no contiene ningún contenido, su longitud será 0.

capacity() - el número de espacios de caracteres que se han asignado . Cuando intenta construir un generador de cadenas con contenido vacío, de forma predeterminada toma el tamaño de inicialización como longitud + 16 que es 0 + 16. entonces la capacidad regresaría 16 aquí.

Nota: La capacidad, que es devuelta por el método capacity(), siempre es mayor o igual que la longitud (generalmente mayor que) y se expandirá automáticamente según sea necesario para acomodar adiciones al generador de cadenas.

La lógica detrás de la función de capacidad:

  1. Si no inicializar StringBuilder con cualquier contenido, la capacidad por defecto será tomado como capacidad de 16 caracteres.
  2. Si inicializa el generador de cadenas con cualquier contenido, la capacidad será la longitud del contenido + 16.
  3. Cuando agrega contenido nuevo al objeto del generador de cadenas, si la capacidad actual no es suficiente para tomar un nuevo valor, crecerá en (capacidad de la matriz anterior + 1) * 2.

Este análisis se toma a partir actual StringBuilder.java code

0

Usted puede ir dentro del código JDK y ver cómo funciona, se basa en una matriz de caracteres: new char[capacity], es similar a cómo los ArrayList obras (When to use LinkedList over ArrayList?) . Ambos usan matrices para ser 'hardware eficientes', el truco es asignar una gran cantidad de memoria y trabajar en ella hasta que se quede sin memoria y necesite que la siguiente gran parte continúe (expandirse/crecer).