CodeGym /Kurslar /C# SELF /StringBuilder sinfi ilə sətirlərlə işləmək

StringBuilder sinfi ilə sətirlərlə işləmək

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Xatırladım ki, C#-da sətirlər — dəyişilməzdir (immutable). Yəni, sətri yaratdıqdan sonra onu dəyişmək olmur: elə bil ki, "dəyişən" bütün əməliyyatlar əslində yaddaşda yeni sətir yaradır.

Məsələn, belə yazanda:

string hello = "Salam";
hello += " dünya!"; // Elə bil hello dəyişdi, amma əslində yeni obyekt yaradıldı!

hello dəyişəni artıq yeni obyektə işarə edir, köhnə obyekt isə (əgər heç yerdə istifadə olunmursa) bir vaxtlar garbage collector tərəfindən silinəcək. Əgər bu cür əməliyyatları dövrədə (loop-da) dəfələrlə edirsənsə, RAM-da "tıxac" yaranır və performans kəskin düşür. Xüsusilə minlərlə və ya milyonlarla sətri birləşdirəndə: hər addımda yeni sətir yaranır, bütün simvollar köçürülür, köhnə obyektlər garbage collector-a qədər asılı qalır və proqram birdən-birə ləng işləməyə başlayır.

Elə bu anda bu mühazirənin qəhrəmanı səhnəyə çıxır — StringBuilder.


using System.Text; // ← mütləq lazımdır!
StringBuilder sb = new StringBuilder("Salam");
sb.Append(" dünya!"); // İndi sətir tez və effektiv dəyişir

StringBuilder ilə tanışlıq

StringBuilderSystem.Text namespace-indən bir sinifdir. Onun işi — böyük sətirləri effektiv şəkildə yaratmaq və yığmaqdır, içindəkiləri daima yeni obyekt yaratmadan dəyişmək.

Analogiya:
Əgər sətir (string) — mozaikanın bir parçasıdırsa və onu yalnız tam dəyişmək mümkündürsə, StringBuilder — maqnit lövhə kimidir, istədiyin qədər “yapışdırıb” və çıxara bilərsən, hər dəfə yeni lövhə yaratmadan.

Nə vaxt StringBuilder istifadə etməyə dəyər?

  • Əgər sətri dəfələrlə dəyişirsənsə (xüsusilə dövrədə).
  • Əgər çoxlu kiçik hissələrdən mətn yığırsansa.
  • Sürət və yaddaş istifadəsi sənin üçün vacibdirsə.

Nə vaxt istifadə ETMƏMƏK lazımdır?

  • Əgər cəmi 1-2 sadə sətir əməliyyatı varsa ― adi string daha rahat və oxunaqlıdır.
  • Əgər həqiqətən (nədənsə) sətirin hər bir vəziyyətini saxlamaq istəyirsənsə.

2. StringBuilder ilə yaradılış və əsas əməliyyatlar

Namespace-i qoşmaq

Başlamaq asandır: namespace-i qoşmağı unutma.

using System.Text;// ← mütləq lazımdır!

Yeni sətir yaratma üsulları


StringBuilder sb1 = new StringBuilder();            // Boş
StringBuilder sb2 = new StringBuilder("Start");     // Başlanğıc mətnlə
StringBuilder sb3 = new StringBuilder(100);         // 100 simvol üçün yer

Əsas metodlar

var sb = new StringBuilder("Başlanğıc");
sb.Append(" + yeni mətn əlavə olundu"); 			// Sona əlavə et
sb.AppendLine(" (bu isə yeni sətrə keçir)"); 	// \n ilə əlavə et
sb.Insert(0, "Start: "); 						// 0-cı mövqedən əlavə et
sb.Remove(0, 7); 								// 0-cı mövqedən 7 simvol sil
sb.Replace("mətn", "STRING"); 					// Bütün "mətn"ləri "STRING" ilə əvəz et
string result = sb.ToString(); 					// Son sətri al

3. StringBuilder-in effektivliyi

Nümunə: performans müqayisəsi

Tutaq ki, ardıcıl 10 000 ədəd sətrə yığmaq lazımdır (bəlkə də bütün qrup yoldaşlarının nömrələrini çıxarmalısan):

Naiv yanaşma (string)

string text = "";
for (int i = 0; i < 10000; i++)
{
    text += i + " "; // Hər addımda yeni sətir yaranır!
}
Console.WriteLine(text.Substring(0, 100) + "..."); // Qısa çıxış üçün

Optimal yanaşma (StringBuilder)

var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
    sb.Append(i).Append(' '); // Zəncirvari əlavə etmək olar!
}
Console.WriteLine(sb.ToString().Substring(0, 100) + "...");

Fərq nədədir?
Birinci variant xeyli yavaş işləyəcək və daha çox yaddaş "yeyəcək". İkinci isə sürətli və RAM-a az tələbatlıdır.

4. StringBuilder-in ən məşhur metodları

Append — sətri və ya başqa tipi əlavə edir (avtomatik sətrə çevirir):

sb.Append("mətn");
sb.Append(123); // 123 "123"-ə çevriləcək
sb.Append('!'); // Simvol

AppendLine — sətri və yeni sətr simvolunu əlavə edir:

sb.AppendLine("sətir"); // "sətir\n" əlavə edəcək

Insert — sətri müəyyən mövqeyə əlavə edir:

sb.Insert(0, "Hello, "); // Əvvələ əlavə et

Remove — bir neçə simvol silir:

sb.Remove(3, 4); // 3-cü mövqedən başlayaraq 4 simvol silir

Replace — bütün alt sətr və ya simvolu əvəz edir:

sb.Replace("old", "new");
sb.Replace('a', 'A');

ToString — hazır sətri qaytarır.

Sətrin qısaldılması

string-dən fərqli olaraq, StringBuilder obyektinə yeni uzunluq verə bilərsən. Onda sətir həmin uzunluğa qədər qısalacaq.

sb.Length = 10; // 10-cu simvoldan sonrası silinir!

5. İşləmə xüsusiyyətləri və tipik səhvlər

Niyə ToString() vacibdir

StringBuilder ilə işləyərkən, "əlində" sətir yox, xüsusi obyekt var. Bir çox metodlar (məsələn, Console.WriteLine) onu rahatlıqla qəbul edir, çünki avtomatik sətrə çevrilə bilir, amma bəzən səni sürpriz gözləyə bilər — əgər təsadüfən adi sətr ilə müqayisə etsən və ya belə bir şey yazsan:

if (sb == "Salam") { ... } // Ups! Bu işləməyəcək, hətta sb-də "Salam" olsa belə

Nəticə false olacaq: müqayisə olunanlar fərqli tipli obyektlərdir.

Düzgün:

if (sb.ToString() == "Salam") { ... }

Mutasiya oluna bilənlik

string-dən fərqli olaraq, StringBuilderdəyişilə biləndir (mutable)! Bir obyektin içindəkiləri istədiyin qədər dəyişə bilərsən, bu da sürət üstünlüyü verir.

İşin sonunda ToString()-i unutma, yoxsa sətr yox, qəribə System.Text.StringBuilder tipli yazı alacaqsan.

Buffer ölçüsü və onun yenidən bölüşdürülməsi

StringBuilder içində simvollardan ibarət massiv saxlayır. Əgər əvvəlcədən bilirsənsə ki, çox uzun sətir "hazırlayacaqsan", konstruktora təxmini uzunluq verə bilərsən — bu bir az sürətləndirəcək.

var bigBuilder = new StringBuilder(50000); // 50 min simvol gözlənilir

Amma səhv etsən — problem deyil! StringBuilder lazım olsa, buffer-i özü böyüdəcək, sadəcə bir az yavaş olacaq.

Yaddaşın dolması?

Teorik olaraq, əgər heç ölçü tanımırsansa və milyardlarla simvol əlavə edirsənsə, OutOfMemoryException ala bilərsən, amma real işlərdə bu demək olar ki, baş vermir.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Sətirlərlə işləmək
Sətirlərlə qabaqcıl işləmə
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION