In Java, all three—String
, StringBuffer
, and StringBuilder
—are used to handle text, but they have key differences in terms of mutability, performance, and thread safety.
1. Summary of Differences
Feature | String | StringBuffer | StringBuilder |
---|---|---|---|
Mutability | ❌ Immutable (cannot be changed) | ✅ Mutable (can be changed) | ✅ Mutable (can be changed) |
Thread Safety | ✅ Yes (Immutable, thread-safe by design) | ✅ Yes (Synchronized methods) | ❌ No (Not synchronized) |
Performance | ❌ Slow (new object created for every modification) | ⚠️ Moderate (thread-safe, but slower due to synchronization) | ✅ Fastest (no synchronization overhead) |
Usage | For fixed text (e.g., keys, constants, config values) | For multi-threaded modifications | For single-threaded modifications |
Example | "Hello" | new StringBuffer("Hello") | new StringBuilder("Hello") |
2. String
(Immutable)
A String
object cannot be changed once created. Any modification creates a new object.
Example: Why String
is Immutable
public class StringExample {
public static void main(String[] args) {
String s = "Hello";
s.concat(" World"); // Creates a new object but doesn't change `s`
System.out.println(s); // Output: Hello
}
}
🔹 Why? "Hello"
stays unchanged because String
is immutable.
✅ Use String
when:
- You have constant values.
- You don’t need frequent modifications.
3. StringBuffer
(Mutable & Thread-Safe)
StringBuffer
is mutable, meaning you can change its content without creating new objects.- It is synchronized, making it thread-safe but slower than
StringBuilder
.
Example: Using StringBuffer
public class StringBufferExample {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb); // Output: Hello World
}
}
✅ Use StringBuffer
when:
- You need thread-safe string modifications (used in multi-threading).
- You are concatenating or modifying strings frequently.
🚨 Downside: Slower than StringBuilder
because it is synchronized.
4. StringBuilder
(Mutable & Fastest)
StringBuilder
is just likeStringBuffer
but not synchronized.- It is faster than
StringBuffer
in single-threaded applications.
Example: Using StringBuilder
public class StringBuilderExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb); // Output: Hello World
}
}
✅ Use StringBuilder
when:
- You are working in a single-threaded environment.
- You need high-performance string modification.
🚀 Benefit: Fastest option because it avoids synchronization.
5. Performance Comparison (String
vs. StringBuffer
vs. StringBuilder
)
Let’s compare their speeds in string concatenation.
public class PerformanceTest {
public static void main(String[] args) {
int iterations = 100000;
long start, end;
// Test String (Slowest)
start = System.nanoTime();
String str = "";
for (int i = 0; i < iterations; i++) {
str += "a"; // New object created each time
}
end = System.nanoTime();
System.out.println("String time: " + (end - start) / 1_000_000.0 + " ms");
// Test StringBuffer (Thread-Safe)
start = System.nanoTime();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < iterations; i++) {
sbf.append("a");
}
end = System.nanoTime();
System.out.println("StringBuffer time: " + (end - start) / 1_000_000.0 + " ms");
// Test StringBuilder (Fastest)
start = System.nanoTime();
StringBuilder sbd = new StringBuilder();
for (int i = 0; i < iterations; i++) {
sbd.append("a");
}
end = System.nanoTime();
System.out.println("StringBuilder time: " + (end - start) / 1_000_000.0 + " ms");
}
}
Expected Output (Typical Results)
String time: 1200 ms
StringBuffer time: 8 ms
StringBuilder time: 5 ms
✅ Why is String
so slow?
- Every modification creates a new object, consuming more memory and processing time.
✅ Why is StringBuilder
fastest?
- It modifies the same object without synchronization overhead.
6. When to Use Which One?
Scenario | Best Choice | Why? |
---|---|---|
Fixed text (constants, keys, messages) | String | Immutable & safe |
String concatenation in a loop (single-threaded) | StringBuilder | Fastest (no synchronization) |
Multi-threaded string modifications | StringBuffer | Thread-safe (synchronized) |
Reading and modifying a large string (single-threaded) | StringBuilder | Best for performance |
Web applications storing constant values | String | Optimized with the String Pool |
Conclusion
- ✅ Use
String
when immutability is required (e.g., constants, database keys). - ✅ Use
StringBuilder
when working in a single-threaded application (fastest option). - ✅ Use
StringBuffer
when multiple threads modify the string (thread-safe but slower).