2010-07-06 14 views
13

ho notato che il metodo restituisce capacityStringBuilder capacità senza un senso logico ... a volte il suo valore è uguale alla lunghezza della stringa altra volta si tratta di una maggiore ...capacità StringBuilder()

c'è un'equazione per sapere qual è la sua logica?

+0

Perché ti interessa la "capacità"? Cresce automaticamente per soddisfare qualsiasi cosa sia necessaria. Puoi giocare con esso per migliorare le prestazioni, ma è ancora asintoticamente lineare. – polygenelubricants

+5

Ci sono domande su 'capacity' vs.' length' nell'esame OCA, quindi per alcune persone il problema ha un significato. –

risposta

3

Questa funzione fa qualcosa di diverso da quello che ci si aspetta - ti dà il numero massimo di caratteri questa memoria di istanza StringBuilder può contenere in questo momento.

String Builder must read

+0

+1 per il link piacevole – codebox

1

EDIT: Scuse - il seguito è riportato informazioni sulle StringBuilder di .NET, e non è strettamente pertinente alla domanda iniziale.

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

StringBuilder alloca spazio per sottostringhe si potrebbe aggiungere ad essa (molto simile Lista crea lo spazio della matrice si avvolge). Se si desidera la lunghezza effettiva della stringa, utilizzare StringBuilder.Length.

+0

Questo articolo riguarda C#, non è vero? –

+0

Sì. La formula è simile a Java ma non esattamente la stessa. – Catchwa

+1

Le mie scuse - Ho visto StringBuilder e presupposto .NET. –

12

Quando si aggiunge alla StringBuilder, la seguente logica accade:

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

dove newCount è il numero di caratteri necessari, e value.length è la dimensione corrente del buffer.

expandCapacity aumenta semplicemente la dimensione del supporto char[]

Il metodo ensureCapacity() è il modo pubblico per chiamare expandCapacity(), ei suoi documenti dire:

Assicura che la capacità sia almeno uguale al specificata minimo. Se la capacità corrente è inferiore all'argomento, viene assegnato un nuovo array interno con una capacità maggiore. La nuova capacità è la maggiore di:

  • L'argomento minimumCapacity.
  • Due volte la vecchia capacità, oltre a 2.

Se l'argomento è MinimumCapacity non positiva, questo metodo non esegue alcuna azione e semplicemente restituisce.

+1

sì ma se ho: StringBuilder str = new StringBuilder(); // capacità 16 str.append ("1111111111111111111"); capacità 32 lunghezza 19 Secondo l'equazione perché la capacità non è 16 * 2 + 2 = 34 ?? – xdevel2000

1

Dal API:

Ogni costruttore stringa ha una capacità. Fintanto che la lunghezza della sequenza di caratteri contenuta nella stringa non supera la capacità, , non è necessario allocare un nuovo buffer interno . Se il buffer interno si espande, viene automaticamente ingrandito il numero .

Ogni volta che si aggiunge qualcosa, c'è un controllo per assicurarsi che lo StringBuilder aggiornato non supererà la sua capacità, e se lo fa, la memoria interna del StringBuilder viene ridimensionato:

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

quando i dati viene addizionata che supera la sua capacità è ri-dimensionato secondo la seguente formula:

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

Vedere il file src.zip fornito con il JDK altre informati sopra. (Sopra i frammenti presi dal 1.6 JDK)

+1

Nella sorgente JDK 7 non ci sono più + 2 caratteri solo il nuovo valore * 2 !!! – xdevel2000

+0

Interessante! Forse l'hanno preso come ottimizzazione? – Catchwa

+0

Forse, comunque, nella documentazione di jdk 7 che non è ancora stata aggiornata! – xdevel2000

10

Cercherò di spiegarlo con qualche esempio.

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 lunghezza della sequenza di caratteri nel generatore di poiché questo StringBuilder non contiene alcun contenuto, la sua lunghezza sarà 0.

capacity() - il numero di spazi di carattere che sono stati stanziati . Quando si tenta di costruire un generatore di stringhe con contenuto vuoto, per impostazione predefinita prende la dimensione di inizializzazione come lunghezza + 16, che è 0 + 16. quindi la capacità tornerebbe 16 qui.

Nota: la capacità, che viene restituita dal metodo capacity(), è sempre maggiore o uguale alla lunghezza (solitamente maggiore di) e si espanderà automaticamente secondo necessità per adattarsi al generatore di stringhe.

La logica dietro la funzione di capacità:

  1. Se non si inizializza StringBuilder con qualsiasi contenuto, la capacità di default sarà preso come capacità di 16 caratteri.
  2. Se si inizializza il generatore di stringhe con qualsiasi contenuto, la capacità sarà la lunghezza del contenuto + 16.
  3. Quando si aggiunge nuovo contenuto all'oggetto stringbuilder, se la capacità corrente non è sufficiente per acquisire un nuovo valore, allora crescerà di (capacità dell'array precedente + 1) * 2.

Questa analisi è prendere da actual StringBuilder.java code

0

Si può andare all'interno del codice JDK e vedere come funziona, si basa su un array di caratteri: new char[capacity], è simile a come i ArrayList opere (When to use LinkedList over ArrayList?) . Entrambi utilizzano gli array per essere "efficienti dal punto di vista hardware", il trucco consiste nell'assegnare una grande quantità di memoria e lavorarci fino a quando non si esaurisce la memoria e si ha bisogno del prossimo grande blocco per continuare (espandere/aumentare).