Capacità StringBuilder ()

Ho notato che il metodo di capacity restituisce la capacità di StringBuilder senza un modo logico … a volte il suo valore è uguale alla lunghezza della stringa, altre volte è maggiore …

c’è un’equazione per sapere quale è la sua logica?

Quando si aggiunge a StringBuilder , si verifica la seguente logica:

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

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

expandCapacity semplicemente aumenta le dimensioni del backing char[]

Il metodo ensureCapacity() è il modo pubblico per chiamare expandCapacity() , e i suoi documenti dicono:

Garantisce che la capacità sia almeno uguale al minimo specificato. Se la capacità corrente è inferiore all’argomento, viene assegnato un nuovo array interno con una capacità maggiore. La nuova capacità è la più grande di:

  • L’argomento minimumCapacity.
  • Due volte la vecchia capacità, più 2.

Se l’argomento minimumCapacity è nonpositivo, questo metodo non accetta azioni e restituisce semplicemente.

Proverò a 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 builder poiché questo stringbuilder non contiene alcun contenuto, la sua lunghezza sarà 0.

capacity() – il numero di spazi dei caratteri che sono stati assegnati. Quando si tenta di build 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 alla base della funzione di capacità:

  1. Se non si inizializza il costruttore di stringhe con alcun contenuto, la capacità predefinita verrà presa come capacità di 16 caratteri.
  2. Se si inizializza il costruttore di stringhe con qualsiasi contenuto, la capacità sarà pari alla lunghezza del contenuto + 16.
  3. Quando aggiungi nuovi contenuti all’object stringbuilder, se la capacità corrente non è sufficiente per assumere un nuovo valore, allora crescerà di (capacità dell’array precedente + 1) * 2.

Questa analisi è presa dal codice StringBuilder.java effettivo

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

String Builder deve leggere

EDIT: Scuse: il seguente è informazioni su StringBuilder di .NET e non è strettamente pertinente alla domanda originale.

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

StringBuilder alloca lo spazio per le sottostringhe che potresti aggiungere ad esso (proprio come List crea lo spazio dell’array che lo avvolge). Se si desidera la lunghezza effettiva della stringa, utilizzare StringBuilder.Length.

Dall’API:

Ogni costruttore di corde ha una capacità. Finché la lunghezza della sequenza di caratteri contenuta nel generatore di stringhe non supera la capacità, non è necessario allocare un nuovo buffer interno. Se il buffer interno fuoriesce, viene automaticamente ingrandito.

Ogni volta che aggiungi qualcosa, c’è un assegno per assicurarti che lo StringBuilder aggiornato non superi la sua capacità, e se lo fa, la memoria interna di StringBuilder viene ridimensionata:

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

Quando vengono aggiunti dati che superano la sua capacità, viene ridimensionato 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 JDK per ulteriori informazioni. (Sopra i frammenti presi dal 1.6 JDK)

Ecco la logica: se definisci una nuova istanza della class StringBuilder senza un costruttore, ad esempio new StringBuilder(); la capacità predefinita è 16. Un costruttore può essere sia int sia una String . Per un costruttore di String , la capacità predefinita viene calcasting in questo modo

 int newCapacity = string.length() + 16; 

Per un costruttore int , la capacità viene calcasting in questo modo

 int newCapacity = intSpecified + 16; 

Se una nuova String viene aggiunta a StringBuilder e la nuova lunghezza della String è maggiore della capacità corrente, la capacità viene calcasting in questo modo:

 int newCapacity = (oldCapacity + 1) * 2; 

Puoi entrare nel codice JDK e vedere come funziona, è basato su un array di caratteri: new char[capacity] , è simile a come funziona ArrayList ( quando utilizzare LinkedList su 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).