MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Clasa StringBuilder

Deși clasa System.String ne oferă o funcționalitate extinsă pentru lucrul cu șiruri de caractere, are totuși câteva dezavantaje. În primul rând, obiectul String reprezintă un șir imutabil. Când executăm o metodă a clasei String, sistemul creează un nou obiect în memorie, alocându-i suficient spațiu.

Ștergerea primului caracter nu este cea mai costisitoare operație. Cu toate acestea, când astfel de operații sunt numeroase și volumul textului pentru care trebuie efectuate aceste operații este semnificativ, pierderile de performanță devin mai importante.

Pentru a rezolva această problemă, în cadrul .NET a fost adăugată o nouă clasă, StringBuilder, care se află în spațiul de nume System.Text. Această clasă reprezintă un șir dinamic.

Crearea unui StringBuilder

Pentru a crea un obiect StringBuilder, putem folosi mai mulți constructori. În primul rând, putem crea un StringBuilder gol:

using System.Text;

StringBuilder sb = new StringBuilder();

Putem inițializa direct obiectul cu un șir definit:

StringBuilder sb = new StringBuilder("Salut lume");

Cu ajutorul metodei ToString() putem obține șirul stocat în StringBuilder:

var sb = new StringBuilder("Hello World");
Console.WriteLine(sb.ToString()); // Hello World

Sau putem pur și simplu să transmitem obiectul StringBuilder:

var sb = new StringBuilder("Hello World");
Console.WriteLine(sb); // Hello World

Lungimea și capacitatea StringBuilder

Pentru a stoca lungimea șirului în clasa StringBuilder, este definită proprietatea Length. Cu toate acestea, există și o a doua valoare - capacitatea memoriei alocate. Această valoare este stocată în proprietatea Capacity.

Capacitatea este memoria alocată pentru obiect. Setarea capacității permite reducerea alocărilor de memorie și, astfel, îmbunătățirea performanței.

Dacă șirul transmis constructorului StringBuilder are o lungime de 16 caractere sau mai puțin, capacitatea inițială în StringBuilder este de 16. Dacă șirul inițial este mai mare de 16 caractere, capacitatea inițială a StringBuilder va fi egală cu lungimea șirului.

De exemplu, să vedem ce conțin aceste proprietăți:

using System.Text;

StringBuilder sb = new StringBuilder("Salut lume");
Console.WriteLine($"Lungime: {sb.Length}"); // Lungime: 10
Console.WriteLine($"Capacitate: {sb.Capacity}"); // Capacitate: 16

Deși în acest caz lungimea este de 10 caractere, capacitatea reală va fi implicit de 16 caractere. Adică vedem că la crearea șirului StringBuilder se alocă mai multă memorie decât este necesar acestui șir.

Când șirul din StringBuilder se mărește și numărul de caractere depășește capacitatea inițială, capacitatea se dublează sau mai mult.

Dacă știm dinainte dimensiunea maximă a obiectului, putem seta direct capacitatea folosind unul dintre constructori și astfel evităm alocările suplimentare de memorie ulterioare.

var sb = new StringBuilder(32);

StringBuilder permite de asemenea să setăm direct șirul și capacitatea:

var sb = new StringBuilder("Salut lume", 32);

Operații cu șiruri în StringBuilder

Pentru operațiile asupra șirurilor, clasa StringBuilder definește mai multe metode:

  • Append: adaugă un subșir la obiectul StringBuilder
  • Insert: inserează un subșir în obiectul StringBuilder, începând de la un anumit index
  • Remove: elimină un număr specific de caractere, începând de la un anumit index
  • Replace: înlocuiește toate aparițiile unui caracter sau subșir cu alt caracter sau subșir
  • AppendFormat: adaugă un subșir la sfârșitul obiectului StringBuilder

Acum să vedem un exemplu de utilizare a metodei Append() și avantajele clasei StringBuilder:

using System.Text;

var sb = new StringBuilder("Titlu: ");
Console.WriteLine(sb); // Titlu:
Console.WriteLine($"Lungime: {sb.Length}"); // 7
Console.WriteLine($"Capacitate: {sb.Capacity}"); // 16

sb.Append(" Ghid");
Console.WriteLine(sb); // Titlu: Ghid
Console.WriteLine($"Lungime: {sb.Length}"); // 12
Console.WriteLine($"Capacitate: {sb.Capacity}"); // 16

sb.Append(" de C#");
Console.WriteLine(sb); // Titlu: Ghid de C#
Console.WriteLine($"Lungime: {sb.Length}"); // 18
Console.WriteLine($"Capacitate: {sb.Capacity}"); // 32

La crearea obiectului StringBuilder, memoria este alocată implicit pentru 16 caractere, deoarece lungimea șirului inițial este mai mică de 16.

Apoi, este utilizată metoda Append - această metodă adaugă un subșir la șir. Deoarece la unirea șirurilor lungimea totală - 12 caractere - depășește capacitatea inițială de 16 caractere, capacitatea inițială se dublează la 32 de caractere.

Dacă lungimea finală a șirului ar fi fost mai mare de 32 de caractere, capacitatea ar fi fost extinsă pentru a se potrivi lungimii șirului.

Apoi, din nou se aplică metoda Append, însă lungimea finală va fi de 18 caractere, ceea ce este mai mic de 32 de caractere și nu se va aloca memorie suplimentară.

Să utilizăm și celelalte metode ale StringBuilder:

var sb = new StringBuilder("Salut lume");
sb.Append("!");
sb.Insert(6, "programare ");
Console.WriteLine(sb); // Salut programare lume!

// înlocuim un cuvânt
sb.Replace("lume", "world");
Console.WriteLine(sb); // Salut programare world!

// eliminăm 11 caractere, începând de la al 6-lea
sb.Remove(6, 11);
Console.WriteLine(sb); // Salut world!

// obținem șirul din obiectul StringBuilder
string text = sb.ToString();
Console.WriteLine(text); // Salut world!

Când să utilizăm clasa String și când StringBuilder?

Microsoft recomandă utilizarea clasei String în următoarele cazuri:

  • Pentru un număr mic de operații și modificări asupra șirurilor
  • La efectuarea unui număr fix de operații de unire. În acest caz, compilatorul poate uni toate operațiile de unire într-una singură
  • Când trebuie să efectuăm operații de căutare extinse la construirea unui șir, de exemplu, IndexOf sau StartsWith. Clasa StringBuilder nu are astfel de metode

Clasa StringBuilder este recomandată în următoarele cazuri:

  • Când numărul de operații și modificări asupra șirurilor este necunoscut în timpul rulării programului
  • Când se preconizează că aplicația va trebui să facă numeroase astfel de operații
← Lecția anterioară Lecția următoare →