StringBuilder in Java
Learn how to efficiently build and modify strings
💡 Think of StringBuilder like a LEGO board where you can easily add, remove, or change pieces! Regular Strings are like completed LEGO models - you can't change them. But StringBuilder is your workspace where you can keep building and modifying until you're happy with the final result!
🔧 What is StringBuilder?
StringBuilder is a mutable (changeable) sequence of characters. Unlike String, you can modify a StringBuilder object after creating it without creating new objects. This makes it much more efficient when you need to make many changes to text.
public class StringBuilderBasics { public static void main(String[] args) { // Creating StringBuilder StringBuilder sb = new StringBuilder("Hello"); System.out.println("Original: " + sb); // Hello // Modifying StringBuilder (changes the same object!) sb.append(" World"); System.out.println("After append: " + sb); // Hello World sb.append("!"); System.out.println("After another append: " + sb); // Hello World! // Compare with String (creates new objects) String str = "Hello"; str = str + " World"; // Creates new String object str = str + "!"; // Creates another new String object }}💪 Why Use StringBuilder?
Performance
Much faster than String concatenation in loops
Building a string with 1000 concatenations: String takes ~500ms, StringBuilder takes ~5ms!
Memory Efficiency
Doesn't create new objects for every change
String concat creates 1000 objects, StringBuilder creates just 1
Flexibility
Easy to insert, delete, or replace text anywhere
Can insert text in the middle without recreating everything
⚡ Performance Comparison
public class PerformanceComparison { public static void main(String[] args) { int iterations = 10000; // BAD: Using String concatenation long start1 = System.currentTimeMillis(); String str = ""; for (int i = 0; i < iterations; i++) { str += "a"; // Creates new String object each time! } long end1 = System.currentTimeMillis(); System.out.println("String concatenation: " + (end1 - start1) + "ms"); // GOOD: Using StringBuilder long start2 = System.currentTimeMillis(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < iterations; i++) { sb.append("a"); // Modifies same object! } long end2 = System.currentTimeMillis(); System.out.println("StringBuilder: " + (end2 - start2) + "ms"); // Result: StringBuilder is MUCH faster! // String: ~500ms, StringBuilder: ~5ms }}🛠️ Common StringBuilder Methods
append()Adds text to the end
sb.append("Hello") → adds "Hello" at the end
insert()Adds text at a specific position
sb.insert(5, "X") → adds "X" at index 5
delete()Removes characters between two positions
sb.delete(2, 5) → removes characters from index 2 to 4
reverse()Reverses the entire string
"Hello" becomes "olleH"
replace()Replaces characters in a range
sb.replace(0, 2, "Hi") → replaces first 2 chars with "Hi"
toString()Converts StringBuilder to String
String s = sb.toString()
📝 append() - Adding to the End
public class AppendExamples { public static void main(String[] args) { StringBuilder sb = new StringBuilder("Hello"); // Append string sb.append(" World"); System.out.println(sb); // Hello World // Append number sb.append(123); System.out.println(sb); // Hello World123 // Append character sb.append('!'); System.out.println(sb); // Hello World123! // Append boolean sb.append(true); System.out.println(sb); // Hello World123!true // Method chaining (append returns StringBuilder) sb = new StringBuilder(); sb.append("Java") .append(" is") .append(" awesome") .append("!"); System.out.println(sb); // Java is awesome! // Building CSV StringBuilder csv = new StringBuilder(); csv.append("Name").append(",") .append("Age").append(",") .append("City"); System.out.println(csv); // Name,Age,City }}✂️ insert() and delete()
public class InsertDeleteExamples { public static void main(String[] args) { // INSERT - add text at specific position StringBuilder sb = new StringBuilder("Java Programming"); // Insert at index 5 sb.insert(5, "Script"); System.out.println(sb); // JavaScript Programming // Insert at beginning sb = new StringBuilder("World"); sb.insert(0, "Hello "); System.out.println(sb); // Hello World // DELETE - remove characters sb = new StringBuilder("Hello World!"); // Delete from index 5 to 11 (11 not included) sb.delete(5, 11); System.out.println(sb); // Hello! // Delete single character sb = new StringBuilder("Helllo"); sb.deleteCharAt(3); // Remove extra 'l' System.out.println(sb); // Hello // Real example: Remove file extension StringBuilder filename = new StringBuilder("document.txt"); int dotIndex = filename.indexOf("."); filename.delete(dotIndex, filename.length()); System.out.println(filename); // document }}🔄 reverse() and replace()
public class ReverseReplaceExamples { public static void main(String[] args) { // REVERSE - flip the entire string StringBuilder sb = new StringBuilder("Hello"); sb.reverse(); System.out.println(sb); // olleH // Check palindrome String word = "racecar"; StringBuilder reversed = new StringBuilder(word).reverse(); boolean isPalindrome = word.equals(reversed.toString()); System.out.println(word + " is palindrome? " + isPalindrome); // true // REPLACE - replace characters in range sb = new StringBuilder("Hello World"); // Replace "World" with "Java" (index 6 to 11) sb.replace(6, 11, "Java"); System.out.println(sb); // Hello Java // Replace multiple times sb = new StringBuilder("I like cats. Cats are cute."); // Find and replace all "cats" with "dogs" int index = 0; while ((index = sb.indexOf("cats", index)) != -1) { sb.replace(index, index + 4, "dogs"); index += 4; } System.out.println(sb); // I like dogs. Cats are cute. // Note: Doesn't replace "Cats" (capital C) - case sensitive! }}📊 Capacity and Length
public class CapacityExample { public static void main(String[] args) { // Default capacity is 16 StringBuilder sb1 = new StringBuilder(); System.out.println("Length: " + sb1.length()); // 0 System.out.println("Capacity: " + sb1.capacity()); // 16 // Capacity with initial string StringBuilder sb2 = new StringBuilder("Hello"); System.out.println("Length: " + sb2.length()); // 5 System.out.println("Capacity: " + sb2.capacity()); // 21 (5 + 16) // Specify initial capacity StringBuilder sb3 = new StringBuilder(100); System.out.println("Length: " + sb3.length()); // 0 System.out.println("Capacity: " + sb3.capacity()); // 100 // Capacity grows automatically StringBuilder sb = new StringBuilder(5); // capacity 5 sb.append("Hello"); // length 5, capacity 5 sb.append(" World"); // needs more space! System.out.println("New capacity: " + sb.capacity()); // 12 (5*2 + 2) // Best practice: estimate capacity to avoid resizing StringBuilder largeText = new StringBuilder(1000); for (int i = 0; i < 100; i++) { largeText.append("Some text "); } // No resizing needed - more efficient! }}🌟 Real-World Examples
public class RealWorldExamples { public static void main(String[] args) { // Example 1: Build HTML dynamically StringBuilder html = new StringBuilder(); html.append("<html>") .append("<body>") .append("<h1>").append("Welcome").append("</h1>") .append("<p>").append("Hello World!").append("</p>") .append("</body>") .append("</html>"); System.out.println(html); // Example 2: Build SQL query StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE "); sql.append("age > 18"); sql.append(" AND "); sql.append("city = 'NYC'"); System.out.println(sql); // Example 3: Join array elements String[] words = {"Java", "is", "awesome"}; StringBuilder sentence = new StringBuilder(); for (int i = 0; i < words.length; i++) { sentence.append(words[i]); if (i < words.length - 1) { sentence.append(" "); } } System.out.println(sentence); // Java is awesome // Example 4: Remove vowels from string String text = "Hello World"; StringBuilder result = new StringBuilder(); for (char c : text.toCharArray()) { if ("aeiouAEIOU".indexOf(c) == -1) { result.append(c); } } System.out.println(result); // Hll Wrld } // Example 5: Format phone number public static String formatPhone(String digits) { if (digits.length() != 10) return digits; StringBuilder formatted = new StringBuilder(); formatted.append("(") .append(digits.substring(0, 3)) .append(") ") .append(digits.substring(3, 6)) .append("-") .append(digits.substring(6)); return formatted.toString(); }}🔑 Key Concepts
Mutable vs Immutable
StringBuilder can be changed; String cannot
sb.append("X") changes sb; str.concat("X") creates new StringCapacity
StringBuilder has internal buffer that grows automatically
Initial capacity 16, doubles when neededNot Thread-Safe
StringBuilder is faster but not safe for multi-threaded use
Use StringBuffer for thread-safety (we'll learn next!)⚠️ Common Mistakes
1. Using String concatenation in loops
❌ String s = ""; for(...) s += x; // Creates many objects!
✅ StringBuilder sb = new StringBuilder(); for(...) sb.append(x);
2. Forgetting to convert to String
❌ return sb; // Returns StringBuilder, not String
✅ return sb.toString(); // Converts to String
3. Using in multi-threaded code
❌ // Multiple threads modifying same StringBuilder
✅ // Use StringBuffer for thread-safety instead
✨ Best Practices
- ✓Use StringBuilder for string concatenation in loops
- ✓Initialize with estimated capacity if you know the final size
- ✓Convert to String only when you need the final result
- ✓Use append() instead of + operator for multiple concatenations
- ✓Remember: StringBuilder is NOT thread-safe
💼 Interview Tips
- •Know the difference between String, StringBuilder, and StringBuffer
- •Understand when to use StringBuilder (performance-critical, single-threaded)
- •Remember StringBuilder is mutable, String is immutable
- •Be able to explain capacity and how StringBuilder grows
- •Know common methods: append(), insert(), delete(), reverse()
- •Understand time complexity: append() is O(1) amortized