String, StringBuilder, StringBuffer
Khi làm việc với dữ liệu kiểu text trong Java cung cấp 3 class String, StringBuffer và StringBuilder. Cơ bản về 3 class này như sau: String là không thể thay đổi (immutable), và không cho phép có class con. StringBuffer, StringBuilder có thể thay đổi (mutable) StringBuilder và StringBuffer là giống nhau, nó chỉ khác biệt tình huống sử dụng có liên quan tới đa luồng (Multi Thread). => về tốc độ xử lý StringBuilder là tốt nhất, sau đó StringBuffer và cuối cùng mới là String.
String Trong java, String là một class đặc biệt, nguyên nhân là nó được sử dụng một cách thường xuyên trong một chương trình, vì vậy đòi hỏi nó phải có hiệu suất và sự mềm dẻo. Đó là lý do tại sao String có tính đối tượng và vừa có tính nguyên thủy (primitive). Ví Dụ về tính nguyên thủy: Chúng ta hoàn toàn có thể khai báo: String s1 = "Hello word" Bạn cũng có thể sử dụng toán tử + để nối 2 string, toán tử này vốn quen thuộc và sử dụng cho các kiểu dữ liệu nguyên thủy như int, float, double. Tính đối tượng: Vì String là một class, vì vậy nó có thể được tạo ra thông qua toán tử new. String object = new String("Hello World");
Các đối tượng String được lưu trữ trên Heap, yêu cầu quản lý bộ nhớ phức tạp và tốn không gian lưu trữ. Hai đối tượng String có nội dung giống nhau lưu trữ trên 2 vùng bộ nhớ khác nhau của Heap. Phương thức Equals vs == Phương thức equals() sử dụng để so sánh 2 đối tượng, với String nó có ý nghĩa là so sánh nội dung của 2 string. Đối với các kiểu tham chiếu (reference) toán tử == có ý nghĩa là so sánh địa chỉ vùng bộ nhớ lưu trữ của đối tượng.
StringBuffer vs StringBuilder StringBuilder và StringBuffer là khá giống nhau, điều khác biệt là tất cả các phương thức của StringBuffer đã được đồng bộ, nó thích hợp khi bạn làm việc với ứng dụng đa luồng, nhiều luồng có thể truy cập vào một đối tượng StringBuffer cùng lúc. Trong khi đó StringBuilder có các phương thức tương tự nhưng không được đồng bộ, vì vậy mà hiệu suất của nó cao hơn, bạn nên sử dụng StringBuilder trong ứng dụng đơn luồng, hoặc sử dụng như một biến địa phương trong một phương thức.String Buffer
String Builder
Hiểu sâu về String
, StringBuilder
, và StringBuffer
trong Java như một Senior Java Developer đòi hỏi bạn phải nắm rõ:
Cấu trúc bộ nhớ và cách hoạt động của từng loại
Khác biệt trong tính bất biến (immutability)
Hiệu suất và cách sử dụng tối ưu
Thread-safety và các tình huống sử dụng phù hợp
Cách JVM xử lý String trong bộ nhớ
Cách tối ưu hóa và tránh memory leak
Hãy đi vào từng khía cạnh một cách chi tiết.
1. String
– Immutable và cơ chế Interning
String
– Immutable và cơ chế Interning📌 Đặc điểm quan trọng:
String
là immutable (bất biến), nghĩa là một khi đã tạo ra thì không thể thay đổi nội dung.Khi thay đổi
String
, một đối tượng mới sẽ được tạo trong heap memory hoặc String Pool.JVM có String Interning, giúp tái sử dụng các chuỗi giống nhau trong String Pool.
🛠 Cách hoạt động của String Pool:
🔥 Lưu ý: Nếu muốn đưa s3
vào String Pool, dùng intern()
📉 Hạn chế của String
:
String
:Việc thay đổi giá trị dẫn đến tạo đối tượng mới, gây tốn bộ nhớ và hiệu suất kém khi xử lý nhiều thay đổi.
Ví dụ tệ khi dùng
String
:
💡 Giải pháp: Dùng StringBuilder
hoặc StringBuffer
.
2. StringBuilder
– Mutable và Hiệu suất cao
StringBuilder
– Mutable và Hiệu suất cao📌 Đặc điểm quan trọng:
StringBuilder
là mutable, tức là có thể thay đổi nội dung mà không tạo đối tượng mới.Sử dụng internal character array, giúp tránh lãng phí bộ nhớ khi thay đổi chuỗi.
Không thread-safe nhưng nhanh hơn
StringBuffer
.
🛠 Cách sử dụng:
📊 Hiệu suất vượt trội so với String
:
String
:🔥 Lưu ý: StringBuilder
nhanh hơn nhưng không thread-safe.
3. StringBuffer
– Thread-safe nhưng chậm hơn
StringBuffer
– Thread-safe nhưng chậm hơn📌 Đặc điểm quan trọng:
Giống
StringBuilder
nhưng hỗ trợ thread-safety bằng cách dùng synchronized.Thích hợp cho môi trường multi-threaded.
🛠 Cách sử dụng:
💡 So sánh tốc độ StringBuffer
vs StringBuilder
:
🔥 Kết luận: Nếu không cần đồng bộ (synchronization), hãy dùng StringBuilder
thay vì StringBuffer
.
4. So sánh chi tiết
Immutable?
✅ Có
❌ Không
❌ Không
Thread-safe?
✅ Có (Immutable)
❌ Không
✅ Có (Synchronized)
Hiệu suất
🚫 Chậm
⚡ Nhanh
🐢 Chậm hơn SB
Dùng trong?
Hằng số, ít thay đổi
Xử lý chuỗi nhanh
Đa luồng
5. Cách JVM xử lý String trong bộ nhớ
📌 Heap vs Stack vs String Pool
Heap Memory: Chứa tất cả các object trong runtime.
Stack Memory: Chứa biến local, reference đến object trên heap.
String Pool (PermGen/Metaspace): Chứa các chuỗi immutable được JVM tối ưu.
💡 String Pool giúp tiết kiệm bộ nhớ nhưng nếu quá nhiều chuỗi, có thể gây OutOfMemoryError.
6. Khi nào dùng gì?
✅ Dùng String
khi:
Chuỗi không thay đổi nhiều.
Chuỗi cần sử dụng nhiều lần để tối ưu bộ nhớ (
intern()
).
✅ Dùng StringBuilder
khi:
Cần thay đổi chuỗi nhiều lần mà không cần thread-safety.
Xử lý văn bản lớn (concat, insert, replace).
✅ Dùng StringBuffer
khi:
Đang làm việc trong môi trường đa luồng.
Last updated