String vs StringBuilder vs StringBuffer in Java
String, StringBuilder, and StringBuffer are used for handling text data in Java. They look similar but differ in mutability, memory usage, thread safety, and performance.
Understanding these classes is extremely important for Java interviews, backend development, memory optimization, and performance tuning.
Main Difference
What is String in Java?
String is an immutable class in Java. Once a String object is created, its value cannot be changed.
Whenever a String is modified, Java creates a new object in memory instead of changing the original object.
String Example
String s = "Java";
s.concat(" Programming");
System.out.println(s);Output
JavaThe original string does not change because String objects are immutable.
Correct Way to Modify String
String s = "Java";
s = s.concat(" Programming");
System.out.println(s);Output
Java ProgrammingWhy String is Immutable
- Provides security
- Improves caching using String Pool
- Makes HashMap keys reliable
- Supports thread safety
- Improves performance in shared environments
Real-World Importance of Immutable Strings
- Database URLs should not change
- File paths must remain constant
- Network connection strings must stay secure
- Usernames and tokens should remain unchanged
String Pool in Java
Java stores String literals inside a special memory area called the String Pool. This helps save memory by reusing identical String objects.
String a = "Java";
String b = "Java";
System.out.println(a == b);Output
trueBoth variables point to the same memory location in the String Pool.
Memory Representation of String
String s1 = "Java";
String s2 = "Java";
String Pool
-------------
"Java" ← s1, s2What is StringBuilder?
StringBuilder is a mutable class introduced in Java 5. It allows modification of text without creating new objects repeatedly.
StringBuilder is faster because it does not use synchronization.
StringBuilder Example
StringBuilder sb = new StringBuilder("Java");
sb.append(" Programming");
System.out.println(sb);Output
Java ProgrammingCommon Methods of StringBuilder
Complex StringBuilder Example
StringBuilder report = new StringBuilder();
report.append("Employee Report\n");
report.append("-------------------\n");
for(int i = 1; i <= 5; i++) {
report.append("Employee ID: ")
.append(i)
.append(" | Salary: ")
.append(i * 5000)
.append("\n");
}
System.out.println(report);Output
Employee Report
-------------------
Employee ID: 1 | Salary: 5000
Employee ID: 2 | Salary: 10000
Employee ID: 3 | Salary: 15000
Employee ID: 4 | Salary: 20000
Employee ID: 5 | Salary: 25000What is StringBuffer?
StringBuffer is also mutable like StringBuilder, but it is thread-safe because its methods are synchronized.
Synchronization makes StringBuffer slower than StringBuilder but safer in multi-threaded applications.
StringBuffer Example
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb);Output
Hello WorldMulti-Threaded Example Using StringBuffer
class Task extends Thread {
static StringBuffer buffer = new StringBuffer("Java");
public void run() {
for(int i = 0; i < 3; i++) {
buffer.append("-").append(i);
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
Task t1 = new Task();
Task t2 = new Task();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(Task.buffer);
}
}StringBuffer prevents data corruption in concurrent environments.
Mutability Concept
Performance Comparison
Repeated String concatenation creates multiple objects and reduces performance.
Performance Problem with String
String result = "";
for(int i = 0; i < 10000; i++) {
result += i;
}This creates thousands of temporary String objects.
Optimized Solution Using StringBuilder
StringBuilder result = new StringBuilder();
for(int i = 0; i < 10000; i++) {
result.append(i);
}This approach is memory efficient and much faster.
Internal Capacity of StringBuilder
StringBuilder maintains an internal character array.
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());Output
16Default capacity is 16 characters. Capacity increases automatically when needed.
Capacity Growth Formula
newCapacity = (oldCapacity * 2) + 2StringBuilder vs StringBuffer
Real-World Use Cases
Complex Real-World Example
Generating a large JSON response in a backend API.
StringBuilder json = new StringBuilder();
json.append("{\n");
json.append(" \"employees\": [\n");
for(int i = 1; i <= 3; i++) {
json.append(" {\n");
json.append(" \"id\": ").append(i).append(",\n");
json.append(" \"name\": \"Employee").append(i).append("\",\n");
json.append(" \"salary\": ").append(i * 10000).append("\n");
json.append(" }");
if(i < 3) {
json.append(",");
}
json.append("\n");
}
json.append(" ]\n");
json.append("}");
System.out.println(json);Generated Output
{
"employees": [
{
"id": 1,
"name": "Employee1",
"salary": 10000
},
{
"id": 2,
"name": "Employee2",
"salary": 20000
},
{
"id": 3,
"name": "Employee3",
"salary": 30000
}
]
}When to Use What
- Use String for fixed or read-only text
- Use StringBuilder for high-performance text modification
- Use StringBuffer when multiple threads modify text simultaneously
Common Beginner Mistakes
- Using String inside loops
- Confusing mutable and immutable objects
- Using StringBuffer in single-threaded applications unnecessarily
- Comparing strings using == instead of equals()
- Ignoring memory overhead caused by String concatenation
Important Interview Questions
- Why is String immutable in Java?
- Difference between StringBuilder and StringBuffer?
- Which is faster and why?
- Why are Strings stored in String Pool?
- Why is String commonly used as HashMap key?
- What happens when String concatenation occurs?
- How does StringBuilder improve performance?
- What is synchronization in StringBuffer?
- Can StringBuilder be used in multi-threading?
- What is the default capacity of StringBuilder?
Final Summary
- String is immutable and memory optimized using String Pool
- StringBuilder is mutable and fastest for modifications
- StringBuffer is mutable and thread-safe
- StringBuilder is preferred in most backend applications
- StringBuffer is useful for concurrent systems
- Choosing the correct class improves memory and performance
Conclusion
String, StringBuilder, and StringBuffer are fundamental classes in Java for handling text operations. String provides immutability and security, StringBuilder provides high performance for dynamic text generation, and StringBuffer provides thread safety for concurrent environments. Understanding their internal behavior, memory concepts, and performance impact is essential for writing efficient Java applications.