Reeșind din contextul problemei de rezolvat, fiecare programator decide care clasă este potrivită de utilizat.
Vom analiza metodele claselor StringBuilder și StringBuffer:
a) append(textNou) - adaugă un text la sfârșitul unui șir de caractere.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
String textInitial = "Salut!";
StringBuffer buffer = new StringBuffer();
buffer.append(textInitial);
buffer.append(" Cum ești?");
System.out.println("StringBuffer: " + buffer);
StringBuilder builder = new StringBuilder();
builder.append(textInitial);
builder.append(" Sper că bine!");
System.out.println("StringBuilder: " + builder);
}}
b) insert(index, text) - permite să adaugi text într-o anumită poziție, nu doar la sfârșit.
Exemplu:public class StringBufferReader {
public static void main(String[] args) {
String textInitial = "Salut lume!";
StringBuffer buffer = new StringBuffer(textInitial);
buffer.insert(6, "frumoasă ");
System.out.println("StringBuffer: " + buffer);
StringBuilder builder = new StringBuilder(textInitial);
builder.insert(6, "dragă ");
System.out.println("StringBuilder: " + builder);
}}
c) delete(start, end) - permite ștergerea unei secvențe de caractere dintre două poziții, începând de la start până la end - 1.
Exemplu:public class StringBufferReader {
public static void main(String[] args) {
String textInitial = "Salut frumoasă lume!";
StringBuffer buffer = new StringBuffer(textInitial);
buffer.delete(6, 15); // șterge caracterele de la index 6 până la 14
System.out.println("StringBuffer după delete: " + buffer);
StringBuilder builder = new StringBuilder(textInitial);
builder.delete(5, 14); // șterge caracterele de la index 5 până la 13
System.out.println("StringBuilder după delete: " + builder);
}}
d) deleteCharAt(int index) - șterge un singur caracter aflat la poziția indicată.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
String textInitial = "Salut lume!";
StringBuffer buffer = new StringBuffer(textInitial);
buffer.deleteCharAt(5); // șterge caracterul de la index 5 (spațiul)
System.out.println("StringBuffer după deleteCharAt: " + buffer.toString());
StringBuilder builder = new StringBuilder(textInitial);
builder.deleteCharAt(0); // șterge primul caracter 'S'
System.out.println("StringBuilder după deleteCharAt: " + builder.toString());
}}
e) replace(start, end, textNou) - adaugă text la sfârșitul unui șir de caractere.
Exemplu: public class StringBufferReader {
public static void main(String[] args) {
String textInitial = "Salut lume!";
StringBuffer buffer = new StringBuffer(textInitial);
buffer.replace(6, 10, "univers"); // înlocuiește "lume" cu "univers"
System.out.println("StringBuffer după replace: " + buffer.toString());
StringBuilder builder = new StringBuilder(textInitial);
builder.replace(0, 5, "Bună"); // înlocuiește "Salut" cu "Bună"
System.out.println("StringBuilder după replace: " + builder.toString());
} }
f) reverse() - inversează toate caracterele din obiectul respectiv.
public class StringBufferReader {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume");
buffer.reverse();
System.out.println("StringBuffer după reverse: " + buffer.toString());
StringBuilder builder = new StringBuilder("Java este frumos");
builder.reverse();
System.out.println("StringBuilder după reverse: " + builder.toString());
}}
g) length() - returnează numărul de caractere din obiectul respectiv.
Exemplu:
public class StringBufferReader{
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume!");
int lungimeBuffer = buffer.length();
System.out.println("Lungimea StringBuffer: " + lungimeBuffer);
StringBuilder builder = new StringBuilder("Java este frumos");
int lungimeBuilder = builder.length();
System.out.println("Lungimea StringBuilder: " + lungimeBuilder);
}}
h) capacity() - arată cât spațiu intern este alocat pentru caractere, adică cât
text poate conține fără să fie nevoie să realoce memorie. Nu este lungimea textului,
spațiul intern disponibil. Dacă capacitatea este depășită, obiectul mărește automat
spațiul intern pentru a stoca caracterele suplimentare, fără a pierde date.
Exemplu:
public class StringBufferReader{
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume!");
System.out.println("Capacity StringBuffer: " + buffer.capacity());
StringBuilder builder = new StringBuilder("Java este frumos");
System.out.println("Capacity StringBuilder: " + builder.capacity());
}}j) charAt(int index) - returnează caracterul aflat la poziția specificată în șir.
Exemplu:public class StringBufferReader {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("Salut lume!");
char c = builder.charAt(0); // primul caracter
System.out.println("Caracterul de la index 0: " + c);
char d = builder.charAt(6); // caracterul de la index 6
System.out.println("Caracterul de la index 6: " + d);
}}
k) setCharAt(int index, char c) - permite să înlocuiți caracterul de la o poziție
specifică cu un alt caracter.
Exemplu:
public class StringBufferReader{
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume!");
buffer.setCharAt(0, 's'); // schimbăm 'S' în 's'
buffer.setCharAt(6, 'L'); // schimbăm 'l' în 'L'
System.out.println("StringBuffer după setCharAt: " + buffer);
StringBuilder builder = new StringBuilder("Java este frumos");
builder.setCharAt(0, 'j'); // schimbăm 'J' în 'j'
builder.setCharAt(5, 'E'); // schimbăm 'e' în 'E'
System.out.println("StringBuilder după setCharAt: " + builder);
}}
k) substring(int start) și substring(int start, int end) - permite
să extragi o porțiune de text din obiectul respectiv, fără să îl modifici.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume!");
String subBuffer = buffer.substring(6); // din index 6 până la final
String subBuffer2 = buffer.substring(0, 5); // din index 0 până la 4
System.out.println("StringBuffer substring 6: " + subBuffer);
System.out.println("StringBuffer substring 0-5: " + subBuffer2);
StringBuilder builder = new StringBuilder("Java este frumos");
String subBuilder = builder.substring(5); // din index 5 până la final
String subBuilder2 = builder.substring(0, 4); // din index 0 până la 3
System.out.println("StringBuilder substring 5: " + subBuilder);
System.out.println("StringBuilder substring 0-4: " + subBuilder2);
}}l) toString() - returnează conținutul obiectului ca un String normal, permițând să îl folosești oriunde este nevoie de un șir de caractere.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Salut lume!");
String textBuffer = buffer.toString();
System.out.println("StringBuffer toString: " + textBuffer);
StringBuilder builder = new StringBuilder("Java este frumos");
String textBuilder = builder.toString();
System.out.println("StringBuilder toString: " + textBuilder);
}}Nu pot să nu subliniez că, datorită caracterului lor mutabil, clasele StringBuilder și StringBuffer permit apelul în lanț al metodelor, astfel încât mai multe operații de manipulare a textului pot fi combinate într-un singur bloc de cod, obținând rapid și elegant rezultatul dorit.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Buna");
buffer.append(" dragi") // adaugă text
.insert(5, " ziua ") // inserează " ziua" la poziția 5
.append(" elevi!") // adaugă la final
.replace(0, 4, "Salut"); // înlocuiește "Buna" cu "Salut"
System.out.println("StringBuffer: " + buffer);
StringBuilder builder = new StringBuilder("Buna");
builder.append(" dimineața") // adaugă text
.insert(4, " tuturor") // inserează " tuturor" la poziția 4
.append("!") // adaugă semn de punctuație
.replace(0, 4, "Salut"); // înlocuiește "Buna" cu "Salut"
System.out.println("StringBuilder: " + builder);
}
}
În același timp, clasa String nu permite apelul în lanț în același mod ca StringBuilder sau StringBuffer, și iată de ce:
a) Obiectele String sunt imutabile.
b) Orice metodă care modifică textul (ex: replace, substring, concat) nu schimbă obiectul original, ci returnează un obiect String nou.
Deși poți scrie apeluri în lanț cu String, fiecare apel creează un nou obiect în memorie, ceea ce este mai puțin eficient comparativ cu StringBuilder sau StringBuffer.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
String text = "Salut lume";
text.replace("Salut", "Buna")
.toUpperCase()
.concat("!");
System.out.println(text); // Salut lume
}}
Observați că, deși am încercat să aplicăm metodele în lanț pe un obiect String, rezultatul afișat nu s-a schimbat, deoarece String este imutabil. În schimb, clasele StringBuilder și StringBuffer, fiind mutabile, permit modificarea directă a obiectului și suportă apelul în lanț al metodelor, oferind rezultate imediate și eficiente.
Vom reface exemplul de mai sus astfel încât, totuși să vedem cum este posibil apelul în lanț în cazul clasei String.
Exemplu:
public class StringBufferReader {
public static void main(String[] args) {
String text = "Salut lume";
String textNou = text.replace("Salut", "Buna")
.toUpperCase()
.concat("!");
System.out.println(textNou);
}
}După cum observăm în acest exemplu, pentru a obține efectul dorit în cazul clasei String, trebuie să salvăm rezultatul fiecărei metode într-o variabilă nouă, deoarece obiectul original rămâne neschimbat.
Clasele StringBuilder și StringBuffer oferă funcții diverse pentru manipularea șirurilor de caractere, fiecare cu avantajele sale, iar pentru o înțelegere rapidă și clară, tabelul comparativ de mai jos sintetizează caracteristicele principale ale acestor două clase și ne vor ajuta să înțelegem care este clasa potrivită de prelucrare a șirurilor de caractere pentru o anumită situație: