W programowaniu często manipulujemy tekstem – łączymy łańcuchy, modyfikujemy je czy tworzymy długie komunikaty. W języku C# podstawowym typem do pracy z tekstem jest string. Jednak gdy wykonujemy wiele operacji na łańcuchach znaków, używanie string może być nieefektywne pod względem wydajności. Dlatego w takich sytuacjach warto sięgnąć po klasę StringBuilder.
Dlaczego warto używać StringBuilder?
• Wydajność: Obiekty typu string są niemutowalne, co oznacza, że po utworzeniu ich wartości nie można zmienić. Każda operacja modyfikacji tworzy nowy obiekt w pamięci. Przy dużej liczbie operacji może to znacząco obciążyć system.
• Oszczędność pamięci: StringBuilder pozwala na dynamiczną modyfikację łańcucha bez tworzenia nowych obiektów, co zmniejsza zużycie pamięci.
• Szybkość: Przy wielu operacjach konkatenacji StringBuilder jest znacznie szybszy niż zwykłe łączenie łańcuchów za pomocą operatora +.
Podstawy użycia StringBuilder
Aby korzystać z klasy StringBuilder, musimy zaimportować przestrzeń nazw:
using System.Text;
Tworzenie obiektu StringBuilder:
StringBuilder sb = new StringBuilder();
Możemy również zainicjalizować go początkowym tekstem:
StringBuilder sb = new StringBuilder("Witaj");
• Inicjalizacja z określoną pojemnością
Możemy zdefiniować początkową pojemność StringBuilder, co może dodatkowo poprawić wydajność.
StringBuilder sb = new StringBuilder(1000); // Rezerwuje miejsce na 1000 znaków
Uwaga na wątkowość
StringBuilder nie jest bezpieczny w kontekście wielowątkowym. Jeśli planujesz używać go w aplikacjach wielowątkowych, musisz zadbać o synchronizację.
Główne metody klasy StringBuilder
1. Append
Dodaje tekst na końcu istniejącego łańcucha.
sb.Append(" świecie!");
// sb teraz zawiera "Witaj świecie!"
2. AppendLine
Dodaje tekst na końcu i wstawia znak nowej linii.
sb.AppendLine("Jak się masz?");
// sb zawiera "Witaj świecie!\nJak się masz?\n"
3. Insert
Wstawia tekst w określonym miejscu.
sb.Insert(6, "piękny ");
// Wstawia "piękny " po 6 znaku
4. Remove
Usuwa określoną liczbę znaków zaczynając od podanego indeksu.
sb.Remove(6, 7);
// Usuwa 7 znaków od indeksu 6
5. Replace
Zamienia wszystkie wystąpienia danego znaku lub ciągu znaków na inny.
sb.Replace("Witaj", "Cześć");
// Zamienia "Witaj" na "Cześć"
6. ToString
Konwertuje zawartość StringBuilder do typu string.
string wynik = sb.ToString();
Przykład praktyczny
Problem: Chcemy zbudować łańcuch zawierający liczby od 1 do 100, oddzielone przecinkami.
Rozwiązanie bez StringBuilder:
string liczby = "";
for (int i = 1; i <= 100; i++)
{
liczby += i + ", ";
}
Problemy:
• Każde dodanie liczby tworzy nowy obiekt string.
• Niska wydajność przy dużej liczbie iteracji.
Rozwiązanie z użyciem StringBuilder:
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 100; i++)
{
sb.Append(i);
if (i < 100)
sb.Append(", ");
}
string liczby = sb.ToString();
Zalety:
• Lepsza wydajność.
• Mniejsze zużycie pamięci.
Ćwiczenie:
Zadanie: Napisz program, który za pomocą StringBuilder tworzy tekst zawierający kolejne dni tygodnia, każdy w nowej linii.
Przykładowe rozwiązanie:
StringBuilder sb = new StringBuilder();
string[] dniTygodnia = { "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela" };
foreach (string dzien in dniTygodnia)
{
sb.AppendLine(dzien);
}
string wynik = sb.ToString();
Console.WriteLine(wynik);