La Classe StringBuffer in Java
- La classe
StringBuffer
in Java consente di gestire stringhe modificabili, a differenza della classeString
che rappresenta stringhe immutabili. StringBuffer
fornisce metodi per aggiungere, inserire, eliminare e sostituire caratteri e sotto-stringhe, rendendo la manipolazione delle stringhe più efficiente.- I metodi come
append()
,insert()
,delete()
,replace()
ereverse()
offrono funzionalità avanzate per lavorare con le stringhe in modo dinamico. - La capacità di
StringBuffer
può essere gestita tramite metodi comeensureCapacity()
etrimToSize()
, permettendo di ottimizzare l'uso della memoria.
La Classe StringBuffer
La libreria standard di Java mette a disposizione la classe StringBuffer
che supporta una stringa modificabile.
Come sappiamo, un oggetto di tipo String
rappresenta sequenze di caratteri immutabili a lunghezza fissa. Al contrario, StringBuffer
rappresenta sequenze di caratteri espandibili e modificabili. StringBuffer
può avere caratteri e sotto-stringhe inseriti nel mezzo o aggiunti alla fine. StringBuffer
crescerà automaticamente per fare spazio a tali aggiunte e spesso ha più caratteri pre-allocati di quanti ne siano effettivamente necessari, per consentire spazio per la crescita.
Vediamo nel dettaglio come funziona StringBuffer
.
Costruttori di StringBuffer
StringBuffer
definisce questi quattro costruttori:
StringBuffer()
StringBuffer(int dimensione)
StringBuffer(String str)
StringBuffer(CharSequence caratteri)
- Il costruttore predefinito (quello senza parametri) riserva spazio per 16 caratteri senza riallocazione.
- La seconda versione accetta un argomento intero,
dimensione
, che imposta esplicitamente la dimensione del buffer. - La terza versione accetta un argomento
String
che imposta il contenuto iniziale dell'oggettoStringBuffer
e riserva spazio per altri 16 caratteri senza riallocazione. - Il quarto costruttore crea un oggetto che contiene la sequenza di caratteri contenuta in
caratteri
e riserva spazio per altri 16 caratteri.
StringBuffer
alloca spazio per 16 caratteri aggiuntivi quando non viene richiesta una lunghezza specifica del buffer, perché la riallocazione è un processo costoso in termini di tempo. Inoltre, le riallocazioni frequenti possono frammentare la memoria. Allocando spazio per alcuni caratteri extra, StringBuffer
riduce il numero di riallocazioni che hanno luogo.
i metodi length
e capacity
La lunghezza corrente di un StringBuffer
può essere trovata tramite il metodo length()
, mentre la capacità totale allocata può essere trovata attraverso il metodo capacity()
. Hanno le seguenti forme generali:
int length()
int capacity()
Ecco un esempio:
// Lunghezza di StringBuffer vs. capacità.
class DemoStringBuffer {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Ciao");
System.out.println("buffer = " + sb);
System.out.println("lunghezza = " + sb.length());
System.out.println("capacità = " + sb.capacity());
}
}
Ecco l'output di questo programma, che mostra come StringBuffer
riserva spazio extra per manipolazioni aggiuntive:
buffer = Ciao
lunghezza = 4
capacità = 20
Poiché sb
è inizializzato con la stringa "Ciao"
quando viene creato, la sua lunghezza è 4. La sua capacità è 20 perché viene automaticamente aggiunto spazio per 16 caratteri aggiuntivi.
Il metodo ensureCapacity
Se vogliamo preallocare spazio per un certo numero di caratteri dopo che un StringBuffer
è stato costruito, possiamo usare ensureCapacity()
per impostare la dimensione del buffer.
Questo è utile se sappiamo in anticipo che aggiungeremo un gran numero di piccole stringhe a un StringBuffer
. ensureCapacity()
ha questa forma generale:
void ensureCapacity(int capacitaMinima)
Qui, capacitaMinima
specifica la dimensione minima del buffer. In ogni caso, il parametro capacitaMinima
è un suggerimento. Per motivi di efficienza, StringBuffer
potrebbe allocare più spazio di quanto richiesto.
Il metodo setLength
Per impostare la lunghezza della stringa all'interno di un oggetto StringBuffer
, si può usare setLength()
. La sua forma generale è mostrata qui:
void setLength(int lunghezza)
Qui, lunghezza
specifica la lunghezza della stringa. Questo valore deve essere non negativo.
Quando si aumenta la dimensione della stringa, caratteri nulli, ossia \0
, vengono aggiunti alla fine. Se si chiama setLength()
con un valore inferiore al valore corrente restituito da length()
, allora i caratteri memorizzati oltre la nuova lunghezza andranno persi. Il programma di esempio demoSetCharAt
nella sezione seguente utilizza setLength()
per accorciare un StringBuffer
.
I metodi charAt
e setCharAt
Il valore di un singolo carattere può essere ottenuto da un StringBuffer
tramite il metodo charAt()
. È possibile impostare il valore di un carattere all'interno di un StringBuffer
utilizzando setCharAt()
. Le loro forme generali sono mostrate qui:
char charAt(int dove)
void setCharAt(int dove, char ch)
Per charAt()
, dove
specifica l'indice del carattere che viene ottenuto. Per setCharAt()
, dove
specifica l'indice del carattere che viene impostato, e ch
specifica il nuovo valore di quel carattere. Per entrambi i metodi, dove
deve essere non negativo e non deve specificare una posizione oltre la fine della stringa.
L'esempio seguente dimostra charAt()
e setCharAt()
:
// Dimostra charAt() e setCharAt().
class DemoSetCharAt {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Ciao");
System.out.println("buffer prima = " + sb);
System.out.println("charAt(1) prima = " + sb.charAt(1));
sb.setCharAt(1, 'i');
sb.setLength(2);
System.out.println("buffer dopo = " + sb);
System.out.println("charAt(1) dopo = " + sb.charAt(1));
}
}
Qui di seguito è riportato l'output prodotto dal programma:
buffer prima = Ciao
charAt(1) prima = i
buffer dopo = Ci
charAt(1) dopo = i
Il metodo getChars
Per copiare una sottostringa di un StringBuffer
in un array, utilizziamo il metodo getChars()
. Ha questa forma generale:
void getChars(int inizioSorgente,
int fineSorgente,
char[] destinazione,
int inizioDestinazione)
Qui, inizioSorgente
specifica l'indice dell'inizio della sotto-stringa, e fineSorgente
specifica un indice che è uno oltre la fine della sotto-stringa desiderata. Questo significa che la sotto-stringa contiene i caratteri da inizioSorgente
fino a fineSorgente
–1. L'array che riceverà i caratteri è specificato da destinazione
. L'indice all'interno di destinazione
al quale la sotto-stringa sarà copiata è passato in inizioDestinazione
. Bisogna prestare attenzione ad assicurarsi che l'array destinazione
sia abbastanza grande da contenere il numero di caratteri nella sotto-stringa specificata.
Il metodo append
Il metodo append()
concatena la rappresentazione stringa di qualsiasi altro tipo di dato alla fine dell'oggetto StringBuffer
che lo invoca. Ha diverse versioni sovraccaricate. Ecco alcune delle sue forme:
StringBuffer append(String str)
StringBuffer append(int num)
StringBuffer append(Object obj)
Prima, viene ottenuta la rappresentazione stringa di ciascun parametro. Poi, il risultato viene aggiunto all'oggetto StringBuffer
corrente. Il buffer stesso viene restituito da ogni versione di append()
. Questo permette di concatenare chiamate successive, come mostrato nell'esempio seguente:
// Dimostra append().
class DemoAppend {
public static void main(String[] args) {
String s;
int a = 42;
StringBuffer sb = new StringBuffer(40);
s = sb.append("a = ").append(a).append("!").toString();
System.out.println(s);
}
}
L'output di questo esempio è mostrato qui:
a = 42!
Il metodo insert
Il metodo insert()
inserisce una stringa in un'altra. È sovraccaricato per accettare valori di tutti i tipi primitivi, più String
, Object
e CharSequence
. Come append()
, ottiene la rappresentazione stringa del valore con cui viene chiamato. Questa stringa viene quindi inserita nell'oggetto StringBuffer
che invoca il metodo. Queste sono alcune delle sue forme:
StringBuffer insert(int indice, String str)
StringBuffer insert(int indice, char ch)
StringBuffer insert(int indice, Object obj)
Qui, indice
specifica l'indice nel punto in cui la stringa verrà inserita nell'oggetto StringBuffer
che invoca il metodo.
Il seguente programma di esempio inserisce "piace "
tra "A me"
e "Java!"
all'interno di un oggetto StringBuffer
:
// Dimostra insert().
class DemoInsert {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("A me Java!");
sb.insert(2, "piace ");
System.out.println(sb);
}
}
L'output di questo esempio è mostrato qui:
A me piace Java!
Il metodo reverse
È possibile invertire i caratteri all'interno di un oggetto StringBuffer
utilizzando reverse()
, mostrato qui:
StringBuffer reverse()
Questo metodo restituisce l'inverso dell'oggetto su cui è stato chiamato. Il seguente programma dimostra reverse()
:
// Utilizzo di reverse() per invertire un StringBuffer.
class DemoInverti {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("abcdef");
System.out.println(s);
s.reverse();
System.out.println(s);
}
}
Ecco l'output prodotto dal programma:
abcdef
fedcba
I metodi delete
e deleteCharAt
È possibile eliminare caratteri all'interno di un StringBuffer
utilizzando i metodi delete()
e deleteCharAt()
. Questi metodi sono mostrati qui:
StringBuffer delete(int indiceInizio, int indiceFine)
StringBuffer deleteCharAt(int posizione)
Il metodo delete()
elimina una sequenza di caratteri dall'oggetto che lo invoca. Qui, indiceInizio
specifica l'indice del primo carattere da rimuovere, e indiceFine
specifica un indice oltre l'ultimo carattere da rimuovere. Quindi, la sotto-stringa eliminata va da indiceInizio
a indiceFine
–1. L'oggetto StringBuffer
risultante viene restituito.
Il metodo deleteCharAt()
elimina il carattere all'indice specificato da posizione
. Restituisce l'oggetto StringBuffer
risultante.
Ecco un programma che dimostra i metodi delete()
e deleteCharAt()
:
// Dimostra delete() e deleteCharAt()
class DemoEliminazione {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Questo è un test.");
sb.delete(4, 7);
System.out.println("Dopo delete: " + sb);
sb.deleteCharAt(0);
System.out.println("Dopo deleteCharAt: " + sb);
}
}
Il seguente output viene prodotto:
Dopo delete: Quesè un test.
Dopo deleteCharAt: uesè un test.
Il metodo replace
È possibile sostituire un insieme di caratteri con un altro insieme all'interno di un oggetto StringBuffer
chiamando replace()
. La sua firma è mostrata qui:
StringBuffer replace(int indiceInizio, int indiceFine, String str)
La sotto-stringa da sostituire è specificata dagli indici indiceInizio
e indiceFine
. Pertanto, la sotto-stringa da indiceInizio
fino a indiceFine
–1 viene sostituita. La stringa di sostituzione è passata in str
. Viene restituito l'oggetto StringBuffer
risultante.
Il seguente programma dimostra replace()
:
// Dimostra replace()
class DemostraReplace {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Questo è un test.");
sb.replace(7, 8, "era");
System.out.println("Dopo replace: " + sb);
}
}
Di seguito è mostrato l'output prodotto dal programma:
Dopo replace: Questo era un test.
Il metodo substring
È possibile ottenere una porzione di un StringBuffer
chiamando substring()
. Ha le seguenti due forme:
String substring(int indiceInizio)
String substring(int indiceInizio, int indiceFine)
La prima forma restituisce la sotto-stringa che inizia a indiceInizio
e arriva fino alla fine dell'oggetto StringBuffer
invocante. La seconda forma restituisce la sotto-stringa che inizia a indiceInizio
e arriva fino a indiceFine
–1. Questi metodi funzionano proprio come quelli definiti per String
che sono stati descritti in precedenza.
Alcuni metodi aggiuntivi di StringBuffer
Oltre ai metodi appena descritti, StringBuffer
ne fornisce altri. Diversi sono riassunti nella seguente tabella:
Metodo | Descrizione |
---|---|
StringBuffer appendCodePoint(int ch) |
Aggiunge un punto di codice Unicode alla fine dell'oggetto invocante. Viene restituito un riferimento all'oggetto. |
int codePointAt(int i) |
Restituisce il punto di codice Unicode nella posizione specificata da i. |
int codePointBefore(int i) |
Restituisce il punto di codice Unicode nella posizione che precede quella specificata da i. |
int codePointCount(int inizio, int fine) |
Restituisce il numero di punti di codice nella porzione della String invocante che sono tra inizio e fine–1. |
int indexOf(String str) |
Cerca nella StringBuffer invocante la prima occorrenza di str. Restituisce l'indice della corrispondenza, o –1 se non viene trovata alcuna corrispondenza. |
int indexOf(String str, int indiceInizio) |
Cerca nella StringBuffer invocante la prima occorrenza di str, iniziando da indiceInizio. Restituisce l'indice della corrispondenza, o –1 se non viene trovata alcuna corrispondenza. |
int lastIndexOf(String str) |
Cerca nella StringBuffer invocante l'ultima occorrenza di str. Restituisce l'indice della corrispondenza, o –1 se non viene trovata alcuna corrispondenza. |
int lastIndexOf(String str, int indiceInizio) |
Cerca nella StringBuffer invocante l'ultima occorrenza di str, iniziando da indiceInizio. Restituisce l'indice della corrispondenza, o –1 se non viene trovata alcuna corrispondenza. |
int offsetByCodePoints(int inizio, int num) |
Restituisce l'indice all'interno della stringa invocante che è num punti di codice oltre l'indice di partenza specificato da inizio. |
CharSequence subSequence(int indiceInizio, int indiceFine) |
Restituisce una sottostringa della stringa invocante, iniziando da indiceInizio e fermandosi a indiceFine. Questo metodo è richiesto dall'interfaccia CharSequence, che è implementata da StringBuffer. |
void trimToSize() |
Richiede che la dimensione del buffer di caratteri per l'oggetto invocante sia ridotta per adattarsi meglio al contenuto corrente. |
Il seguente programma dimostra indexOf()
e lastIndexOf()
:
class DemoIndexOf {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("uno due uno");
int i;
i = sb.indexOf("uno");
System.out.println("Primo indice: " + i);
i = sb.lastIndexOf("uno");
System.out.println("Ultimo indice: " + i);
}
}
L'output è mostrato qui:
Primo indice: 0
Ultimo indice: 8