StringBuilder and StringBuffer
Master mutable strings in Java for efficient text manipulation and better performance.
Why StringBuilder and StringBuffer?
Remember that String objects in Java are immutable (cannot be changed). Every time you modify a String, Java creates a new object in memory. This is inefficient when you need to perform many modifications.
StringBuilder and StringBuffer solve this problem. They are mutable, meaning you can modify them without creating new objects every time. This makes them much faster for operations like concatenation in loops.
- Both StringBuilder and StringBuffer are mutable (can be changed)
- More efficient than String for multiple modifications
- Perfect for building strings dynamically in loops
- Reduce memory overhead and improve performance
💡 Key Difference: StringBuilder is faster but not thread-safe. StringBuffer is thread-safe but slightly slower. For single-threaded applications, use StringBuilder.
String vs StringBuilder Performance
Let's see why StringBuilder is more efficient than regular String concatenation.
Example: Performance Comparison
public class StringVsBuilder {
public static void main(String[] args) {
// Using String (inefficient - creates many objects)
long startTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < 10000; i++) {
str += "Hello"; // Creates new object each time
}
long endTime = System.currentTimeMillis();
System.out.println("String time: " + (endTime - startTime) + "ms");
// Using StringBuilder (efficient - modifies same object)
startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append("Hello"); // Modifies existing object
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder time: " + (endTime - startTime) + "ms");
}
}
String time: 156ms StringBuilder time: 2ms
Explanation:
- String concatenation in loops creates thousands of temporary objects
- StringBuilder modifies the same object, avoiding memory waste
- StringBuilder can be 50-100x faster for multiple concatenations
Creating StringBuilder Objects
You can create StringBuilder objects in different ways depending on your needs.
Example: Different Ways to Create StringBuilder
public class CreateStringBuilder {
public static void main(String[] args) {
// Method 1: Empty StringBuilder (default capacity 16)
StringBuilder sb1 = new StringBuilder();
System.out.println("Empty capacity: " + sb1.capacity());
// Method 2: With initial capacity
StringBuilder sb2 = new StringBuilder(50);
System.out.println("Custom capacity: " + sb2.capacity());
// Method 3: With initial string
StringBuilder sb3 = new StringBuilder("Hello");
System.out.println("With string: " + sb3);
System.out.println("Length: " + sb3.length());
// StringBuffer (similar syntax, thread-safe)
StringBuffer sbf = new StringBuffer("Java");
System.out.println("StringBuffer: " + sbf);
}
}
Empty capacity: 16 Custom capacity: 50 With string: Hello Length: 5 StringBuffer: Java
Explanation:
new StringBuilder()- Creates empty builder with default capacity of 16 charactersnew StringBuilder(50)- Creates with specific capacity for better performancenew StringBuilder("Hello")- Initializes with existing stringcapacity()returns allocated space,length()returns actual content size
Essential StringBuilder Methods
1. append() - Add to End
Adds string, number, or character to the end of the StringBuilder.
Example: sb.append("Hello") adds "Hello" at the end
2. insert() - Add at Position
Inserts content at a specific index position.
Example: sb.insert(5, "World") inserts "World" at index 5
3. delete() - Remove Characters
Removes characters from start index to end index.
Example: sb.delete(0, 5) removes first 5 characters
4. reverse() - Reverse String
Reverses the entire character sequence.
Example: sb.reverse() reverses "Hello" to "olleH"
5. replace() - Replace Portion
Replaces characters from start index to end index with new string.
Example: sb.replace(0, 5, "Hi") replaces first 5 chars with "Hi"
6. toString() - Convert to String
Converts StringBuilder to regular String object.
Example: String result = sb.toString()
StringBuilder Methods in Action
Let's explore the most commonly used StringBuilder methods with practical examples.
Example: Working with StringBuilder Methods
public class StringBuilderMethods {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Java");
System.out.println("Original: " + sb);
// append() - Add to end
sb.append(" Programming");
System.out.println("After append: " + sb);
// insert() - Add at position
sb.insert(4, " 17");
System.out.println("After insert: " + sb);
// replace() - Replace portion
sb.replace(0, 4, "Python");
System.out.println("After replace: " + sb);
// delete() - Remove characters
sb.delete(6, 9);
System.out.println("After delete: " + sb);
// reverse() - Reverse string
sb.reverse();
System.out.println("After reverse: " + sb);
// Convert back to String
String result = sb.toString();
System.out.println("Final String: " + result);
}
}
Original: Java After append: Java Programming After insert: Java 17 Programming After replace: Python 17 Programming After delete: Python Programming After reverse: gnimmargorP nohtyP Final String: gnimmargorP nohtyP
Explanation:
- All methods modify the same StringBuilder object (no new objects created)
insert(4, " 17")adds " 17" at index 4delete(6, 9)removes characters from index 6 to 8 (end is exclusive)toString()converts StringBuilder to regular String when needed
More StringBuilder Methods
Explore additional useful methods for string manipulation.
Example: Additional Methods
public class MoreMethods {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello World");
// charAt() - Get character at index
System.out.println("Character at 6: " + sb.charAt(6));
// setCharAt() - Change character at index
sb.setCharAt(6, 'J');
System.out.println("After setCharAt: " + sb);
// deleteCharAt() - Remove character at index
sb.deleteCharAt(5);
System.out.println("After deleteCharAt: " + sb);
// substring() - Extract portion (doesn't modify)
String sub = sb.substring(0, 5);
System.out.println("Substring: " + sub);
System.out.println("Original unchanged: " + sb);
// length() and capacity()
System.out.println("Length: " + sb.length());
System.out.println("Capacity: " + sb.capacity());
// setLength() - Truncate or extend
sb.setLength(5);
System.out.println("After setLength(5): " + sb);
}
}
Character at 6: W After setCharAt: Hello Jorld After deleteCharAt: HelloJorld Substring: Hello Original unchanged: HelloJorld Length: 10 Capacity: 27 After setLength(5): Hello
Explanation:
setCharAt(6, 'J')replaces character at index 6 with 'J'deleteCharAt(5)removes single character at index 5substring()extracts but doesn't modify the StringBuildersetLength(5)truncates to 5 characters or extends with null chars
StringBuilder vs StringBuffer
Both classes have identical methods but differ in thread-safety and performance.
Example: StringBuilder vs StringBuffer
public class BuilderVsBuffer {
public static void main(String[] args) {
// StringBuilder (not thread-safe, faster)
StringBuilder builder = new StringBuilder("Java");
builder.append(" is");
builder.append(" awesome");
System.out.println("StringBuilder: " + builder);
// StringBuffer (thread-safe, slightly slower)
StringBuffer buffer = new StringBuffer("Python");
buffer.append(" is");
buffer.append(" cool");
System.out.println("StringBuffer: " + buffer);
// Both have same methods
builder.reverse();
buffer.reverse();
System.out.println("Reversed StringBuilder: " + builder);
System.out.println("Reversed StringBuffer: " + buffer);
}
}
StringBuilder: Java is awesome StringBuffer: Python is cool Reversed StringBuilder: emosewa si avaJ Reversed StringBuffer: looc si nohtyP
Explanation:
- Both have identical API and methods
- StringBuilder is faster for single-threaded applications
- StringBuffer has synchronized methods for thread safety
- Use StringBuilder unless you need thread-safety
Practical Use Case: Building Dynamic Text
A real-world example showing when to use StringBuilder over String concatenation.
Example: Creating HTML Table Dynamically
public class DynamicHTML {
public static void main(String[] args) {
String[] students = {"Alice", "Bob", "Charlie"};
int[] marks = {85, 92, 78};
// Using StringBuilder to build HTML efficiently
StringBuilder html = new StringBuilder();
html.append("\n");
html.append(" Name Marks \n");
for (int i = 0; i < students.length; i++) {
html.append(" ");
html.append("").append(students[i]).append(" ");
html.append("").append(marks[i]).append(" ");
html.append(" \n");
}
html.append("
");
System.out.println(html.toString());
}
}
<table> <tr><th>Name</th><th>Marks</th></tr> <tr><td>Alice</td><td>85</td></tr> <tr><td>Bob</td><td>92</td></tr> <tr><td>Charlie</td><td>78</td></tr> </table>
Explanation:
- StringBuilder is perfect for building complex strings in loops
- Method chaining:
append().append().append()makes code concise - Much more efficient than string concatenation for dynamic content
- Common use cases: HTML generation, CSV creation, log messages
When to Use Each Type
Use String When:
Working with fixed text that won't change, or performing only 1-2 concatenations.
Examples: Configuration values, displaying static messages, storing names
Use StringBuilder When:
Building strings dynamically in single-threaded applications (most common case).
Examples: Loops with concatenation, dynamic HTML/XML, building queries
Use StringBuffer When:
Building strings in multi-threaded environments where thread safety is required.
Examples: Shared data between threads, concurrent string operations
Key Points to Remember
- Mutability: StringBuilder and StringBuffer can be modified, String cannot
- Performance: StringBuilder is fastest, StringBuffer is thread-safe but slower, String is slowest for multiple modifications
- Default choice: Use StringBuilder for dynamic string building in loops
- Conversion: Use toString() to convert StringBuilder/StringBuffer back to String
- Capacity: Automatically grows when needed, but setting initial capacity improves performance
- Method chaining: Most methods return the same object, allowing chained calls
🎯 Best Practice: Always use StringBuilder when concatenating strings in a loop. It can improve performance by 50-100x compared to regular String concatenation!