Bỏ qua để đến nội dung

StringBuilder

1. Vấn đề: nối chuỗi bằng + trong vòng lặp rất tốn kém

Phần tiêu đề “1. Vấn đề: nối chuỗi bằng + trong vòng lặp rất tốn kém”

String bất biến, mỗi lần dùng + để nối chuỗi, Java phải tạo ra một đối tượng String hoàn toàn mới và sao chép toàn bộ nội dung cũ sang. Trong vòng lặp có nhiều lần lặp, điều này rất lãng phí bộ nhớ và thời gian:

String result = "";
for (int i = 0; i < 10000; i++) {
result += i + ","; // MỖI lần lặp tạo ra một String mới, sao chép lại toàn bộ nội dung cũ
}

StringBuilder là một đối tượng có thể thay đổi (mutable) - nó dùng một vùng nhớ đệm bên trong để nối chuỗi mà không tạo đối tượng mới ở mỗi bước:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i).append(","); // nối trực tiếp vào cùng một đối tượng, hiệu quả hơn nhiều
}
String result = sb.toString(); // chuyển về String khi cần dùng
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // "Hello World" - nối vào cuối
sb.insert(5, ","); // "Hello, World" - chèn tại vị trí
sb.replace(0, 5, "Hi"); // "Hi, World" - thay thế đoạn [0, 5)
sb.delete(0, 3); // " World" - xóa đoạn [0, 3)
sb.reverse(); // đảo ngược chuỗi
sb.deleteCharAt(0); // xóa một ký tự tại vị trí
System.out.println(sb.length()); // độ dài hiện tại
System.out.println(sb.toString()); // chuyển sang String

StringBuilder cũng hỗ trợ charAt(), indexOf(), substring() tương tự String.

Java có hai lớp tương tự: StringBuilderStringBuffer. Chúng có API gần như giống hệt nhau, khác biệt duy nhất là:

  • StringBuffer: các phương thức được đồng bộ hóa (synchronized) - an toàn khi nhiều luồng (thread) cùng truy cập, nhưng chậm hơn
  • StringBuilder: không đồng bộ hóa - nhanh hơn, dùng khi chỉ có một luồng truy cập (trường hợp phổ biến nhất)

👉 Trong hầu hết chương trình thông thường (không đa luồng), nên ưu tiên dùng StringBuilder.

  • Nối chuỗi lặp lại nhiều lần bằng + rất kém hiệu quả vì String bất biến
  • StringBuilder là chuỗi có thể thay đổi (mutable), dùng append() để nối hiệu quả
  • insert(), replace(), delete(), reverse() là các thao tác chỉnh sửa phổ biến khác
  • Ưu tiên StringBuilder hơn StringBuffer trừ khi cần an toàn đa luồng