CodeGym /Các khóa học /C# SELF /Lớp StringBuilder để làm việc với chuỗi

Lớp StringBuilder để làm việc với chuỗi

C# SELF
Mức độ, Bài học
Có sẵn

1. Giới thiệu

Nhắc lại nhé, chuỗi trong C# là không thay đổi được (immutable). Tức là, sau khi tạo ra chuỗi thì không thể sửa nó: mọi thao tác tưởng như "thay đổi" chuỗi thật ra tạo ra một chuỗi mới trong bộ nhớ.

Ví dụ, khi bạn viết:

string hello = "Xin chào";
hello += " thế giới!"; // Có vẻ hello đã thay đổi, nhưng thật ra là tạo object mới!

Biến hello trỏ đến object mới, còn cái cũ (nếu không dùng nữa) sẽ bị garbage collector xóa đi. Nếu bạn làm kiểu này trong vòng lặp nhiều lần, có thể bị "ngập" RAM và hiệu năng tụt dốc. Đặc biệt nếu bạn ghép hàng ngàn hay hàng triệu chuỗi: mỗi bước lại tạo chuỗi mới, copy hết ký tự, object cũ treo đến khi dọn rác, và chương trình của bạn tự nhiên lag luôn.

Đây là lúc nhân vật chính của bài này xuất hiện — StringBuilder.


using System.Text; // ← bắt buộc luôn!
StringBuilder sb = new StringBuilder("Xin chào");
sb.Append(" thế giới!"); // Giờ chuỗi thay đổi nhanh và gọn lẹ

Làm quen với StringBuilder

StringBuilder là class trong namespace System.Text. Nhiệm vụ của nó là tạo và ghép chuỗi lớn hiệu quả, thay đổi nội dung mà không phải tạo object mới liên tục.

Ví dụ dễ hiểu:
Nếu chuỗi (string) là một miếng ghép tranh mà bạn chỉ có thể thay cả miếng, thì StringBuilder giống như bảng nam châm, bạn muốn dán/tháo miếng nào cũng được, không cần tạo bảng mới mỗi lần thêm/bớt miếng ghép.

Khi nào nên dùng StringBuilder?

  • Nếu bạn thay đổi chuỗi nhiều lần (đặc biệt trong vòng lặp).
  • Nếu bạn ghép text từ nhiều mảnh nhỏ.
  • Nếu bạn quan tâm tốc độ và tiết kiệm RAM.

Khi nào KHÔNG nên dùng?

  • Nếu bạn chỉ có 1-2 thao tác đơn giản với chuỗi ― dùng string cho nhanh và dễ đọc.
  • Nếu bạn thực sự muốn (vì lý do gì đó) lưu lại từng trạng thái chuỗi riêng biệt.

2. Tạo và thao tác cơ bản với StringBuilder

Kết nối namespace

Bắt đầu rất đơn giản: nhớ import namespace nhé.

using System.Text;// ← bắt buộc luôn!

Cách tạo chuỗi mới


StringBuilder sb1 = new StringBuilder();            // Rỗng
StringBuilder sb2 = new StringBuilder("Bắt đầu");   // Có text khởi tạo
StringBuilder sb3 = new StringBuilder(100);         // Dự phòng 100 ký tự

Các method chính

var sb = new StringBuilder("Khởi đầu");
sb.Append(" + thêm text mới"); 			        // Thêm vào cuối
sb.AppendLine(" (và đây là có xuống dòng)"); 	// Thêm với \n
sb.Insert(0, "Bắt đầu: "); 				        // Chèn ở vị trí 0
sb.Remove(0, 7); 							        // Xóa 7 ký tự từ vị trí 0
sb.Replace("text", "STRING"); 				        // Thay tất cả "text" thành "STRING"
string result = sb.ToString(); 				        // Lấy chuỗi kết quả

3. Hiệu năng của StringBuilder

Ví dụ: so sánh tốc độ

Giả sử bạn cần ghép chuỗi từ 10 000 số liên tiếp (kiểu như được giao in ra tất cả số điện thoại bạn cùng lớp):

Cách ngây thơ (string)

string text = "";
for (int i = 0; i < 10000; i++)
{
    text += i + " "; // Mỗi bước lại tạo chuỗi mới!
}
Console.WriteLine(text.Substring(0, 100) + "..."); // In ngắn cho gọn

Cách tối ưu (StringBuilder)

var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
    sb.Append(i).Append(' '); // Ghép chuỗi liên tục!
}
Console.WriteLine(sb.ToString().Substring(0, 100) + "...");

Khác biệt ở đâu?
Cách đầu sẽ chạy chậm thấy rõ và có thể "ăn" nhiều RAM hơn hẳn. Cách sau thì nhanh và nhẹ nhàng cho bộ nhớ.

4. Các method phổ biến nhất của StringBuilder

Append — thêm chuỗi hoặc kiểu khác (tự động chuyển thành chuỗi):

sb.Append("text");
sb.Append(123); // 123 sẽ thành "123"
sb.Append('!'); // Ký tự

AppendLine — thêm chuỗi + ký tự xuống dòng:

sb.AppendLine("chuỗi"); // Thêm "chuỗi\n"

Insert — chèn chuỗi vào vị trí xác định:

sb.Insert(0, "Hello, "); // Chèn vào đầu

Remove — xóa một số ký tự:

sb.Remove(3, 4); // Xóa 4 ký tự từ vị trí 3

Replace — thay tất cả chuỗi con hoặc ký tự:

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

ToString — trả về chuỗi hoàn chỉnh.

Cắt chuỗi

Khác với string, object kiểu StringBuilder có thể gán giá trị mới cho thuộc tính độ dài. Khi đó chuỗi sẽ bị cắt ngắn lại.

sb.Length = 10; // Mọi thứ sau ký tự thứ 10 sẽ biến mất!

5. Đặc điểm và lỗi thường gặp

Tại sao ToString() lại quan trọng

Khi bạn làm việc với StringBuilder, bạn đang cầm một object đặc biệt chứ không phải chuỗi. Nhiều method (ví dụ Console.WriteLine) vẫn nhận nó vì nó tự chuyển thành chuỗi, nhưng đôi khi bạn sẽ bị bất ngờ — nếu bạn so sánh với chuỗi thường hoặc làm kiểu như:

if (sb == "Xin chào") { ... } // Ôi! Không chạy đâu, dù sb chứa "Xin chào"

Kết quả sẽ là false: so sánh là giữa object khác loại.

Đúng phải là:

if (sb.ToString() == "Xin chào") { ... }

Tính mutable

Khác với string, StringBuilder là thay đổi được (mutable)! Một object có thể đổi nội dung bao nhiêu lần cũng được, nhờ đó mà nhanh hơn nhiều.

Nhớ gọi ToString() khi xong việc với object, không thì bạn sẽ nhận được text kiểu System.Text.StringBuilder chứ không phải chuỗi bạn muốn.

Kích thước buffer và tự mở rộng

Bên trong StringBuilder là một mảng ký tự. Nếu bạn biết trước sẽ "chế biến" chuỗi rất dài, có thể truyền độ dài dự kiến vào constructor — sẽ nhanh hơn chút.

var bigBuilder = new StringBuilder(50000); // Dự kiến 50 nghìn ký tự

Nhưng nếu đoán sai cũng không sao! StringBuilder sẽ tự mở rộng buffer khi cần, chỉ là hơi chậm hơn chút thôi.

Tràn bộ nhớ?

Lý thuyết thì nếu bạn "quẩy" quá đà và thêm hàng tỷ ký tự, có thể gặp OutOfMemoryException, nhưng thực tế thì hiếm khi nào gặp lắm.

2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Thay đổi chuỗi bằng các phương thức của `StringBuilder`
Thay đổi chuỗi bằng các phương thức của `StringBuilder`
2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Tạo danh sách số bằng `StringBuilder`
Tạo danh sách số bằng `StringBuilder`
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Làm việc với chuỗi
Làm việc nâng cao với chuỗi
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION