Java - StringBuilder and StringBuffer in Java

Introduction

In Java, strings are commonly used to store and manipulate text. The String class is immutable, which means that once a String object is created, its contents cannot be changed.

For example:

String name = "Java";
name = name + " Programming";

In this example, the original "Java" String is not modified. Instead, Java creates a new String object containing "Java Programming".

This behavior is useful for maintaining safety and reliability, but it can become inefficient when a program performs many string modifications.

Java provides two mutable classes for this purpose:

  • StringBuilder

  • StringBuffer

Both allow the contents of a character sequence to be modified without creating a new object for every operation.


1. What is StringBuilder?

StringBuilder is a class in Java used to create and modify mutable sequences of characters.

Unlike String, a StringBuilder object can be changed after it is created.

Example

StringBuilder sb = new StringBuilder("Hello");

sb.append(" Java");

System.out.println(sb);

Output:

Hello Java

The append() operation modifies the existing StringBuilder object instead of creating a completely new string for every modification.

StringBuilder is particularly useful when many string operations are performed inside loops or repeatedly during program execution.


2. Creating a StringBuilder

A StringBuilder can be created in several ways.

Empty StringBuilder

StringBuilder sb = new StringBuilder();

This creates an empty StringBuilder.

StringBuilder with Initial Text

StringBuilder sb = new StringBuilder("Hello");

The object initially contains:

Hello

StringBuilder with Initial Capacity

StringBuilder sb = new StringBuilder(50);

This creates a StringBuilder with an initial capacity of 50 characters.

Capacity refers to the amount of storage allocated internally before the object needs to expand its storage.


3. What is StringBuffer?

StringBuffer is another Java class used to create mutable sequences of characters.

Like StringBuilder, it allows text to be modified without creating a new object for every operation.

Example:

StringBuffer sb = new StringBuffer("Hello");

sb.append(" Java");

System.out.println(sb);

Output:

Hello Java

The major difference between StringBuilder and StringBuffer is related to thread safety.

StringBuffer's commonly used modification methods are synchronized, making it suitable for situations where the same object may be accessed by multiple threads.


4. StringBuilder vs StringBuffer

Both classes provide similar functionality, but they are designed for slightly different situations.

Feature StringBuilder StringBuffer
Mutability Mutable Mutable
Thread safety Not synchronized Synchronized
Performance Generally faster Generally slower
Introduced Java 5 Java 1.0
Suitable for Single-threaded operations Multi-threaded shared access
Main advantage Better performance Thread-safe operations

For most normal string manipulation tasks where the object is not shared between multiple threads, StringBuilder is generally preferred.


5. append() Method

The append() method adds data to the end of the existing character sequence.

Example:

StringBuilder sb = new StringBuilder("Hello");

sb.append(" World");

System.out.println(sb);

Output:

Hello World

It can append different types of values.

StringBuilder sb = new StringBuilder();

sb.append("Age: ");
sb.append(25);
sb.append(", Marks: ");
sb.append(85.5);

System.out.println(sb);

Output:

Age: 25, Marks: 85.5

This makes append() useful when constructing a large piece of text from multiple values.


6. insert() Method

The insert() method adds characters at a specified position.

Example:

StringBuilder sb = new StringBuilder("Hello World");

sb.insert(6, "Java ");

System.out.println(sb);

Output:

Hello Java World

Here, index 6 specifies the position where "Java " is inserted.

The index starts from zero.

For "Hello World":

H e l l o   W o r l d
0 1 2 3 4 5 6 7 8 9 10

7. delete() Method

The delete() method removes characters between two specified indexes.

Example:

StringBuilder sb = new StringBuilder("Hello Java World");

sb.delete(6, 11);

System.out.println(sb);

Output:

Hello World

The starting index is included, while the ending index is excluded.

Therefore, delete(6, 11) removes characters at indexes 6 through 10.


8. deleteCharAt() Method

The deleteCharAt() method removes a single character from a specified position.

Example:

StringBuilder sb = new StringBuilder("Hello");

sb.deleteCharAt(1);

System.out.println(sb);

Output:

Hllo

The character at index 1, which is e, is removed.


9. replace() Method

The replace() method replaces a portion of the character sequence with another sequence.

Example:

StringBuilder sb = new StringBuilder("Hello World");

sb.replace(6, 11, "Java");

System.out.println(sb);

Output:

Hello Java

The characters from index 6 to index 10 are replaced by "Java".


10. reverse() Method

The reverse() method reverses the entire character sequence.

Example:

StringBuilder sb = new StringBuilder("Java");

sb.reverse();

System.out.println(sb);

Output:

avaJ

The same method is available in StringBuffer.

StringBuffer sb = new StringBuffer("Hello");

sb.reverse();

System.out.println(sb);

Output:

olleH

11. length() Method

The length() method returns the number of characters currently stored.

Example:

StringBuilder sb = new StringBuilder("Java");

System.out.println(sb.length());

Output:

4

If characters are added, the length changes.

StringBuilder sb = new StringBuilder("Java");

sb.append(" Programming");

System.out.println(sb.length());

The length is updated automatically after the modification.


12. capacity() Method

A StringBuilder or StringBuffer has an internal capacity used to store characters.

The capacity() method returns the current capacity.

Example:

StringBuilder sb = new StringBuilder();

System.out.println(sb.capacity());

A newly created StringBuilder has a default internal capacity specified by the Java implementation/API contract.

When more space is required, the object automatically expands its capacity.

You can also specify an initial capacity:

StringBuilder sb = new StringBuilder(100);

System.out.println(sb.capacity());

This creates an object with an initial capacity of 100 characters.

Capacity and length are different concepts.

For example:

StringBuilder sb = new StringBuilder(50);
sb.append("Java");

System.out.println(sb.length());
System.out.println(sb.capacity());

The length represents the number of characters currently stored, while capacity represents the allocated storage available before expansion is required.


13. charAt() Method

The charAt() method returns the character at a particular index.

Example:

StringBuilder sb = new StringBuilder("Java");

System.out.println(sb.charAt(2));

Output:

v

Indexes begin at zero.

Therefore:

J = 0
a = 1
v = 2
a = 3

14. setCharAt() Method

The setCharAt() method changes the character at a particular position.

Example:

StringBuilder sb = new StringBuilder("Java");

sb.setCharAt(0, 'K');

System.out.println(sb);

Output:

Kava

This demonstrates the mutable nature of StringBuilder.

With a String object, a character cannot be directly changed in the same way.


15. Converting StringBuilder to String

A StringBuilder can be converted into a String using the toString() method.

Example:

StringBuilder sb = new StringBuilder("Hello Java");

String result = sb.toString();

System.out.println(result);

Output:

Hello Java

This is useful when a method or API requires a String rather than a StringBuilder.

The same approach works with StringBuffer:

StringBuffer sb = new StringBuffer("Hello Java");

String result = sb.toString();

16. Why StringBuilder is More Efficient for Repeated Modifications

Consider the following code:

String result = "";

for (int i = 1; i <= 5; i++) {
    result = result + i;
}

System.out.println(result);

Repeated concatenation can create multiple String objects because String is immutable.

A StringBuilder can perform the same operation more efficiently:

StringBuilder result = new StringBuilder();

for (int i = 1; i <= 5; i++) {
    result.append(i);
}

System.out.println(result);

Output:

12345

For larger amounts of repeated concatenation, this difference can become significant.


17. StringBuilder in Loops

StringBuilder is particularly useful when constructing text inside loops.

Example:

StringBuilder numbers = new StringBuilder();

for (int i = 1; i <= 5; i++) {
    numbers.append(i).append(" ");
}

System.out.println(numbers);

Output:

1 2 3 4 5

Instead of repeatedly creating new String objects, the same mutable StringBuilder object is modified.


18. When to Use StringBuilder

StringBuilder is appropriate when:

  1. A program performs frequent string modifications.

  2. Text is constructed inside loops.

  3. Performance is important.

  4. The mutable character sequence does not need synchronization.

  5. The object is used within a single thread or is otherwise safely confined.

For example, generating a large report, constructing a SQL statement, creating formatted output, or combining many pieces of text can benefit from StringBuilder.


19. When to Use StringBuffer

StringBuffer can be considered when:

  1. Multiple threads may access the same mutable character sequence.

  2. Synchronized methods are desirable for protecting operations on that shared object.

  3. The application specifically relies on StringBuffer's synchronized API behavior.

However, synchronization alone does not automatically make every larger sequence of operations logically thread-safe. If several operations must be treated as one atomic action, additional synchronization or other concurrency techniques may still be necessary.


20. Important Difference Between String, StringBuilder, and StringBuffer

The three classes can be understood as follows:

String

String is immutable.

String s = "Hello";
s = s + " Java";

The original String object is not modified.

StringBuilder

StringBuilder is mutable and is generally preferred for efficient repeated modifications when synchronization is not required.

StringBuilder sb = new StringBuilder("Hello");
sb.append(" Java");

The existing StringBuilder is modified.

StringBuffer

StringBuffer is mutable and provides synchronized methods for many of its operations.

StringBuffer sb = new StringBuffer("Hello");
sb.append(" Java");

The existing StringBuffer is modified.


21. Practical Example Using StringBuilder

The following program constructs a student report:

public class StudentReport {
    public static void main(String[] args) {

        StringBuilder report = new StringBuilder();

        report.append("Student Report\n");
        report.append("Name: Rahul\n");
        report.append("Subject: Java\n");
        report.append("Marks: 85\n");
        report.append("Result: Pass");

        System.out.println(report);
    }
}

Output:

Student Report
Name: Rahul
Subject: Java
Marks: 85
Result: Pass

This is a good example of using StringBuilder to construct a large piece of text step by step.


22. Practical Example Using StringBuffer

public class StringBufferExample {
    public static void main(String[] args) {

        StringBuffer message = new StringBuffer("Java");

        message.append(" Programming");
        message.insert(0, "Learn ");
        message.replace(6, 10, "Advanced");

        System.out.println(message);
    }
}

StringBuffer provides many of the same manipulation methods as StringBuilder.

The important distinction is that StringBuffer's methods are synchronized, whereas StringBuilder's are not.


23. Advantages of StringBuilder

The main advantages of StringBuilder are:

  • It is mutable.

  • It avoids creating a new String object for every modification.

  • It is generally faster than StringBuffer for unsynchronized use.

  • It provides methods such as append(), insert(), delete(), replace(), and reverse().

  • It is useful for repeated string manipulation.

  • It works especially well when constructing strings inside loops.


24. Advantages of StringBuffer

The main advantages of StringBuffer are:

  • It is mutable.

  • It supports repeated string manipulation.

  • Its commonly used methods are synchronized.

  • It can be useful when a mutable character sequence is shared among multiple threads and synchronized access is appropriate.


25. Important Points to Remember

StringBuilder and StringBuffer are both mutable character sequences.

StringBuilder is generally preferred for normal string manipulation when thread synchronization is not needed.

StringBuffer provides synchronized methods and is therefore designed with thread-safe access to individual operations in mind.

String should be preferred when immutability is desirable and the text does not need frequent modification.

The most commonly used StringBuilder and StringBuffer methods include:

append()
insert()
delete()
deleteCharAt()
replace()
reverse()
length()
capacity()
charAt()
setCharAt()
toString()

The key concept to remember is:

String        → Immutable
StringBuilder → Mutable, generally faster, not synchronized
StringBuffer  → Mutable, synchronized methods

Therefore, when a Java program needs to repeatedly modify text, StringBuilder is usually the first choice. StringBuffer is more appropriate when synchronized access to the mutable character sequence is specifically required.