Skip to content

Latest commit

 

History

History
328 lines (228 loc) · 7.88 KB

File metadata and controls

328 lines (228 loc) · 7.88 KB

StringBuilder, StringBuffer, and StringTokenizer


1. Why Mutable Strings?

We know that String objects in Java are immutable, meaning:

Once created, their content cannot change.

So, for frequent string modifications (like in loops, concatenation, or text building), immutable strings are slow and memory-inefficient.

Hence, Java provides:

  • StringBuffermutable + thread-safe

  • StringBuildermutable + fast (non-thread-safe)


2. StringBuilder — Fast, Mutable String

Definition:

A mutable sequence of characters (not synchronized).

Introduced in Java 1.5 to replace StringBuffer in single-threaded programs.


Key Features

Property Description
Mutability ✅ Yes
Thread-safe ❌ No
Synchronization ❌ Not synchronized
Performance Fast
Best Use Case Single-threaded applications

Example: Basic Usage

public class StringBuilderDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        sb.append(" Java");         // add text
        sb.insert(5, ",");          // insert comma
        sb.replace(0, 5, "Hi");     // replace part
        sb.delete(3, 5);            // delete part
        sb.reverse();               // reverse string

        System.out.println(sb);
    }
}

Output:

avaJ,iH

Important Methods

Method Description Example
append() Adds text at end sb.append(" World")
insert(int, String) Inserts text at position sb.insert(5, "Java")
replace(int, int, String) Replace substring sb.replace(0, 5, "Hi")
delete(int, int) Delete substring sb.delete(2, 5)
reverse() Reverses sequence sb.reverse()
capacity() Returns buffer size sb.capacity()
ensureCapacity(int) Ensures buffer capacity sb.ensureCapacity(100)
setLength(int) Truncates or pads sb.setLength(10)

Internal Working

  • Uses a character array buffer internally.

  • Initial capacity = 16 characters (by default).

  • When buffer is full → grows automatically using:

    newCapacity = (oldCapacity * 2) + 2
    

Example:

StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());  // 16
sb.append("abcdefghijklmnopq");     // exceeds 16
System.out.println(sb.capacity());  // (16*2)+2 = 34

Performance Example

public class BuilderPerformance {
    public static void main(String[] args) {
        long start, end;

        StringBuilder sb = new StringBuilder();
        start = System.currentTimeMillis();
        for(int i = 0; i < 100000; i++)
            sb.append(i);
        end = System.currentTimeMillis();

        System.out.println("StringBuilder time: " + (end - start) + "ms");
    }
}

✅ Much faster than using normal String concatenation inside loops.


3. StringBuffer — Thread-Safe Mutable String

Definition:

A mutable sequence of characters like StringBuilder, but thread-safe (all methods are synchronized).

Introduced in Java 1.0 (legacy class).


Key Features

Property Description
Mutability ✅ Yes
Thread-safe ✅ Yes
Synchronization ✅ Synchronized
Performance 🐢 Slower (due to locking)
Best Use Case Multi-threaded programs

Example: Basic Usage

public class StringBufferDemo {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("Hello");
        sb.append(" World");
        sb.insert(6, "Java ");
        sb.delete(0, 6);
        sb.reverse();
        System.out.println(sb);
    }
}

Output:

dlroW avaJ

Important Methods

Method Description
append() Add text at end
insert() Insert text
delete() Remove characters
reverse() Reverse string
capacity() Show current buffer capacity
trimToSize() Reduce buffer to actual size

Example: Thread Safety Demo

public class ThreadSafetyDemo {
    public static void main(String[] args) throws InterruptedException {
        StringBuffer buffer = new StringBuffer();

        Runnable r = () -> {
            for(int i = 0; i < 1000; i++) {
                buffer.append("x");
            }
        };

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Length = " + buffer.length()); // Expected 2000
    }
}

✅ Output is always correct because methods are synchronized.

If you replace StringBuffer with StringBuilder → ❌ unpredictable results (not thread-safe).


4. StringTokenizer — Splitting Strings

Before split() existed, Java had the StringTokenizer class to break a string into tokens (words, pieces, etc.).


Definition:

A legacy class from java.util used to divide strings into tokens based on delimiters.

import java.util.StringTokenizer;

public class TokenizerDemo {
    public static void main(String[] args) {
        String text = "Java,Python,C++,Go";
        StringTokenizer st = new StringTokenizer(text, ",");

        while(st.hasMoreTokens()) {
            System.out.println(st.nextToken());
        }
    }
}

Output:

Java
Python
C++
Go

Constructor Forms

Constructor Description
StringTokenizer(String str) Uses default delimiter (space)
StringTokenizer(String str, String delim) Custom delimiter
StringTokenizer(String str, String delim, boolean returnDelims) Option to return delimiters as tokens

Example with Multiple Delimiters

String data = "apple,banana;grapes.orange";
StringTokenizer st = new StringTokenizer(data, ",;.");

while(st.hasMoreTokens()) {
    System.out.println(st.nextToken());
}

Output:

apple
banana
grapes
orange

Note:

  • StringTokenizer is deprecated in modern Java usage.

  • Prefer using:

    String[] parts = str.split("[,;.]");

    or

    Scanner scanner = new Scanner(str);

Key Takeaways

  • String → Immutable

  • StringBuilder → Mutable + Fast (not thread-safe)

  • StringBuffer → Mutable + Safe (thread-safe, slower)

  • StringTokenizer → Legacy, replaced by split() and Scanner


Interview Nuggets

  • Q: Why use StringBuilder over String for concatenation? A: To avoid creating multiple temporary string objects (faster and memory-efficient).

  • Q: How does StringBuilder grow internally? A: Automatically doubles capacity (newCap = oldCap * 2 + 2).

  • Q: Can StringBuffer and StringBuilder be converted to String? A: Yes, using .toString() method.

  • Q: Is StringTokenizer still used? A: Rarely. It’s considered legacy; String.split() or regex are preferred.