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à:
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).