What is the difference between String, StringBuilder, and StringBuffer in Java?
Table of Contents
1. Short Answer
The main differences between String, StringBuilder, and StringBuffer in Java are:
- String: Immutable, thread-safe, but less efficient for string manipulation
- StringBuilder: Mutable, not thread-safe, most efficient for string manipulation
- StringBuffer: Mutable, thread-safe, but less efficient than StringBuilder
2. String Class
The String class in Java is immutable, meaning its value cannot be changed after creation.
2.1 Characteristics
- Immutable - once created, cannot be modified
- Thread-safe by design
- Stored in String Pool for memory efficiency
- Inefficient for frequent modifications
2.2 Example
String str = "Hello";
str = str + " World"; // Creates new String object
System.out.println(str); // Output: Hello World
Note
Each string concatenation operation creates a new String object, which can be inefficient for multiple operations.
3. StringBuilder Class
StringBuilder is a mutable sequence of characters, introduced in Java 5.
3.1 Characteristics
- Mutable - can be modified after creation
- Not thread-safe
- Most efficient for string manipulation
- Better performance than StringBuffer
3.2 Example
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Modifies existing object
System.out.println(sb.toString()); // Output: Hello World
Best Practice
Use StringBuilder when you need to perform multiple string manipulations in a single-threaded environment.
4. StringBuffer Class
StringBuffer is similar to StringBuilder but is thread-safe.
4.1 Characteristics
- Mutable - can be modified after creation
- Thread-safe - synchronized methods
- Slower than StringBuilder due to synchronization
- Legacy class (since Java 1.0)
4.2 Example
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // Thread-safe modification
System.out.println(sb.toString()); // Output: Hello World
Important
StringBuffer's thread safety comes at a performance cost. Use it only when thread safety is required.
5. Detailed Comparison
Let's compare these classes in detail:
| Feature | String | StringBuilder | StringBuffer |
|---|---|---|---|
| Mutability | Immutable | Mutable | Mutable |
| Thread Safety | Yes | No | Yes |
| Performance | Slow for modifications | Fastest | Slower than StringBuilder |
| Memory Usage | High for modifications | Low | Low |
| Introduced in | Java 1.0 | Java 5 | Java 1.0 |
6. Performance Analysis
Let's analyze the performance characteristics:
6.1 Concatenation Performance
// String concatenation (slow)
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // Creates new String each time
}
// StringBuilder (fast)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i); // Modifies existing object
}
// StringBuffer (slower than StringBuilder)
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < 1000; i++) {
sbf.append(i); // Thread-safe modification
}
6.2 Performance Comparison
- String concatenation: O(n²) time complexity
- StringBuilder: O(n) time complexity
- StringBuffer: O(n) time complexity with synchronization overhead
7. Use Cases
When to use each class:
7.1 Use String when:
- String value won't change
- Thread safety is required
- Working with string literals
- Using as keys in collections
7.2 Use StringBuilder when:
- Performing multiple string modifications
- Working in a single-threaded environment
- Performance is critical
- Building complex strings
7.3 Use StringBuffer when:
- Thread safety is required
- Multiple threads will modify the string
- Working with legacy code
8. Best Practices
Follow these best practices when working with strings in Java:
- Use String for constants and immutable strings
- Use StringBuilder for string manipulation in single-threaded environments
- Use StringBuffer only when thread safety is required
- Initialize StringBuilder with appropriate capacity
- Avoid string concatenation in loops
- Use string literals when possible
// Good practice: Initialize with capacity
StringBuilder sb = new StringBuilder(100);
// Good practice: Chain methods
sb.append("Hello")
.append(" ")
.append("World");
// Bad practice: String concatenation in loop
String result = "";
for (String str : strings) {
result += str; // Creates new String each iteration
}
9. Conclusion
Understanding the differences between String, StringBuilder, and StringBuffer is crucial for writing efficient Java code.
Key takeaways:
- String is immutable and thread-safe
- StringBuilder is mutable and most efficient
- StringBuffer is mutable and thread-safe
- Choose the appropriate class based on requirements
- Consider performance implications
- Follow best practices for string manipulation