Deep Dive into Java's String, StringBuilder, and StringBuffer

Core String Operations in Java

String Construction Techniques

Java offers multiple ways to instantiate String objects: - Literally: String greeting = "Hello World";

  • Explicit instantiation: String copy = new String("Hello World");
  • From character array: ``` char[] chars = {'H', 'e', 'l', 'l', 'o'}; String fromArray = new String(chars);
    
    

Key Instance Methods

Length and emptiness:

String text = "Java";
int len = text.length();     // returns 4
boolean empty = text.isEmpty(); // returns false

Character access:

char first = text.charAt(0); // 'J'
// throws IndexOutOfBoundsException if index is invalid

String Comparison Strategies

  • ==: Compares memory addresses — rarely appropriate for content comparison.
  • .equals(Object): Compares actual character sequences (case-sensitive).
  • .equalsIgnoreCase(String): Case-insensitive content comparison.
  • .compareTo(String): Returns negative/zero/positive based on lexicographic ordering.

Searching Within Strings

  • indexOf(char) / indexOf(String): First occurrence from start.
  • lastIndexOf(char) / lastIndexOf(String): First occurrence from end.
  • indexOf(char, int fromIndex): Search starting at specified offset.

Type Conversion Utilities

Numeric ↔ String:

String numStr = String.valueOf(123);     // "123"
int value = Integer.parseInt("456");     // 456
double d = Double.parseDouble("3.14");   // 3.14

Casing transformations:

String upper = "hello".toUpperCase();   // "HELLO"
String lower = "WORLD".toLowerCase();   // "world"

Formatting:

String formatted = String.format("Value: %d, Name: %s", 42, "Alice");
// "Value: 42, Name: Alice"

Content Manipulation

Replacement:

  • .replace(char old, char new) or .replace(CharSequence target, CharSequence replacement)
  • .replaceFirst(String regex, String replacement)
  • .replaceAll(String regex, String replacement)

Splitting:

String sentence = "apple,banana,cherry";
String[] parts = sentence.split(","); // ["apple", "banana", "cherry"]

// Escape regex metacharacters: ".", "|", "*", "+"
String withDots = "a.b.c";
String[] segments = withDots.split("\\."); // ["a", "b", "c"]

Substrings:

String source = "Programming";
String sub = source.substring(3);        // "gramming"
String range = source.substring(0, 3);   // "Pro"

Immutability and Its Implications

The String class is immutable — every operation that appears to modify it returns a new instance. Internally:

  • String wraps a final char[] value, preventing reassignment of the array reference.
  • The class itself is declared final, disallowing inheritance-based overrides.
  • Immutability enables safe sharing across threads, efficient hash caching, and string interning.

Consequently, repeated concatenation like s += "x" inside loops creates many short-lived objects — a performance anti-pattern.

Mutable Alternatives: StringBuilder vs StringBuffer

Design Diffferences

Feature StringBuilder StringBuffer
Thread Safety Not synchronized — faster Synchronized methods — thread-safe but slower
Use Case Single-threaded contexts Multi-threaded environments requiring safety

Common Mutable Operations

StringBuilder builder = new StringBuilder("Start");

builder.append(" Middle");           // "Start Middle"
builder.insert(5, "Inserted");      // "StartInserted Middle"
builder.delete(0, 5);               // "Inserted Middle"
builder.replace(0, 9, "Replaced");  // "Replaced Middle"
builder.reverse();                  // "elgnidtS depmocer"

String result = builder.toString(); // final immutable output

Practical Conversion Patterns - String → StringBuilder/StringBuffer: new StringBuilder(str)

  • StringBuilder/StringBuffer → String: buffer.toString()

Common Algorithmic Exercises


1. First non-repeating character:

public static char firstUniqueChar(String s) {
    Map<character integer=""> freq = new HashMap<>();
    for (char c : s.toCharArray()) {
        freq.put(c, freq.getOrDefault(c, 0) + 1);
    }
    for (char c : s.toCharArray()) {
        if (freq.get(c) == 1) return c;
    }
    return '\0';
}</character>

2. Parse integer manually (with overflow handling):

public static int parseInteger(String input) {
    if (input == null || input.trim().isEmpty()) return 0;
    input = input.trim();
    
    int sign = 1, start = 0;
    long result = 0;
    
    if (input.charAt(0) == '-') {
        sign = -1;
        start = 1;
    } else if (input.charAt(0) == '+') {
        start = 1;
    }
    
    for (int i = start; i < input.length(); i++) {
        char c = input.charAt(i);
        if (c < '0' || c > '9') break;
        result = result * 10 + (c - '0');
        if (result * sign > Integer.MAX_VALUE) return Integer.MAX_VALUE;
        if (result * sign < Integer.MIN_VALUE) return Integer.MIN_VALUE;
    }
    
    return (int) (result * sign);
}

Tags: java string immutable thread-safety StringBuilder

Posted on Sun, 17 May 2026 14:02:40 +0000 by saad|_d3vil