In primo luogo c'è un problema con la tua domanda:
String s = "orange";
s.append("apple");
qui due oggetti vengono creati
corretta, vengono creati due oggetti, la stringa "arancia" e la stringa "mele ", all'interno di StringBuffer/StringBuilder non verrà creato alcun oggetto se non si verifica un overflow del buffer. Quindi quelle linee di codice creano 2 o 3 oggetti.
StringBuilder s = new StringBuilder("Orange");
s.append("apple");
Ora qui solo un oggetto viene creato
Non so dove si ottiene che, qui si crea un oggetto StringBuilder, una stringa "Orange", una "mela" String , per un totale di 3 oggetti, o 4 se si trabocca il buffer StringBuilder. (Conto la creazione dell'array come creazione dell'oggetto).
ho letto la tua domanda come, come può fare lo StringBuilder accodamento senza creare un nuovo oggetto (quando il buffer non è sorvolato)?
Si dovrebbe guardare StringBuilder
, poiché è l'implementazione non thread-safe.Il codice è interessante e facile da leggere. Ho aggiunto i commenti in linea.
Come struttura interna c'è un array di caratteri, non una stringa. Inizialmente è costruito con lunghezza 16 e verrà aumentato ogni volta che la capacità viene superata. Se le stringhe da aggiungere rientrano nell'array char, non è necessario creare nuovi oggetti.
StringBuilder
estende AbstractStringBuilder
, dove troverete il seguente codice:
/**
* The value is used for character storage.
*/
char value[];
Poiché non tutti l'array verrà utilizzato in un dato momento, un'altra variabile importante è la lunghezza:
/**
* The count is the number of characters used.
*/
int count;
Ci sono molti sovraccarichi di append, ma il più interessante è il seguente:
public AbstractStringBuilder append(String str) {
if (str == null) str = "null"; //will literally append "null" in case of null
int len = str.length(); //get the string length
if (len == 0) return this; //if it's zero, I'm done
int newCount = count + len; //tentative new length
if (newCount > value.length) //would the new length fit?
expandCapacity(newCount); //oops, no, resize my array
str.getChars(0, len, value, count); //now it will fit, copy the chars
count = newCount; //update the count
return this; //return a reference to myself to allow chaining
}
String.getChars (int srcBegin, int srcEnd, char [] dst, int dstBegin) Copia i caratteri da questa stringa nell'array di caratteri di destinazione.
Così, il metodo append è abbastanza semplice, l'unica magia sinistra per scoprire è il expandCapacity
, eccolo:
void expandCapacity(int minimumCapacity) {
//get the current length add one and double it
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) { //if we had an integer overflow
newCapacity = Integer.MAX_VALUE; //just use the max positive integer
} else if (minimumCapacity > newCapacity) { //is it enough?
//if doubling wasn't enough, use the actual length computed
newCapacity = minimumCapacity;
}
//copy the old value in the new array
value = Arrays.copyOf(value, newCapacity);
}
Arrays.copyOf (char [] originali, int newLength) copia il array specificato, troncamento o riempimento con caratteri null (se necessario) in modo che la copia abbia la lunghezza specificata.
Nel nostro caso, imbottitura, poiché stiamo espandendo la lunghezza.
Ci sono alcune ipotesi in questione che non sono corretti. 'new StringBuilder()' e 'new String()' crea due oggetti. –
Era la mia domanda? ;) –