Strings & StringBuilder
BeginnerUnderstand String immutability, the string pool, all essential String methods, and when to use StringBuilder for performance.
Overview
String is the most-used class in Java and one of the most misunderstood. Strings are immutable — every operation that appears to modify a String actually creates a new object. Java maintains a String pool in the heap where interned literals are stored and reused. For building strings dynamically (in loops, for example), StringBuilder is dramatically faster than using + because it avoids creating throwaway String objects on every concatenation.
Immutability & the String Pool
When you write String s = "hello", Java looks in the string pool first. If "hello" already exists there, s points to that same object. If not, a new object is created in the pool. This is why == works for literal comparisons — they point to the same pooled instance. But String s = new String("hello") always creates a new heap object outside the pool, so == fails.
String.intern() manually adds a string to the pool and returns the pooled reference. In practice, rely on .equals() for all string comparisons — never ==.
public class StringPool {
public static void main(String[] args) {
// Literals go to the string pool
String a = "hello";
String b = "hello";
System.out.println(a == b); // true — same pooled object
System.out.println(a.equals(b)); // true
// new String() bypasses the pool
String c = new String("hello");
System.out.println(a == c); // false — different heap objects
System.out.println(a.equals(c)); // true — same content
// intern() returns the pooled reference
String d = c.intern();
System.out.println(a == d); // true — now pointing to pool
// Strings are immutable — every "change" creates a new object
String s = "Java";
s = s + " 21"; // s now points to a NEW String "Java 21"
System.out.println(s); // Java 21
// The original "Java" object is unchanged (and eventually GC'd)
}
}Essential String Methods
The String class has 60+ methods. These are the ones you need to know cold for both daily development and interviews:
length(), charAt(i), indexOf(str), lastIndexOf(str) substring(start), substring(start, end) — end is exclusive toUpperCase(), toLowerCase(), trim(), strip() — strip() is Unicode-aware (Java 11+) startsWith(prefix), endsWith(suffix), contains(seq) replace(old, new), replaceAll(regex, new) split(regex), join(delim, parts) isEmpty(), isBlank() — isBlank() also catches whitespace-only (Java 11+) compareTo(), compareToIgnoreCase() formatted(args) / String.format(fmt, args) — printf-style
public class StringMethods {
public static void main(String[] args) {
String s = " Hello, Java World! ";
// Trimming
System.out.println(s.trim()); // "Hello, Java World!"
System.out.println(s.strip()); // same, but Unicode-aware (Java 11)
String t = "Hello, Java World!";
System.out.println(t.length()); // 18
System.out.println(t.charAt(7)); // J
System.out.println(t.indexOf("Java")); // 7
System.out.println(t.substring(7, 11)); // Java
System.out.println(t.toUpperCase()); // HELLO, JAVA WORLD!
System.out.println(t.replace("Java", "Python")); // Hello, Python World!
// Split and join
String csv = "one,two,three";
String[] parts = csv.split(",");
System.out.println(parts.length); // 3
System.out.println(String.join(" | ", parts)); // one | two | three
// Blank / empty
System.out.println("".isEmpty()); // true
System.out.println(" ".isBlank()); // true (Java 11+)
// Formatting
String msg = "Score: %d / %d (%.1f%%)".formatted(87, 100, 87.0);
System.out.println(msg); // Score: 87 / 100 (87.0%)
// chars() stream (Java 9+)
long vowels = t.chars()
.filter(c -> "aeiouAEIOU".indexOf(c) >= 0)
.count();
System.out.println("Vowels: " + vowels); // 5
}
}StringBuilder & Performance
Using + inside a loop is O(n²) because each concatenation allocates a new String and copies all previous characters. StringBuilder uses a resizable char[] buffer internally — append() is amortized O(1).
StringBuffer is the thread-safe equivalent of StringBuilder, but its synchronization overhead makes it rarely useful. Prefer StringBuilder in single-threaded code (i.e., almost always).
The compiler automatically converts simple a + b + c into a StringBuilder chain, but NOT when concatenation is inside a loop — that optimisation must be done manually.
public class StringBuilderDemo {
public static void main(String[] args) {
// BAD: O(n²) — creates a new String on every iteration
String bad = "";
for (int i = 0; i < 5; i++) bad += i; // avoid in real code
System.out.println(bad); // 01234
// GOOD: O(n) — StringBuilder's buffer grows as needed
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) sb.append(i);
System.out.println(sb.toString()); // 01234
// StringBuilder API
StringBuilder demo = new StringBuilder("Hello");
demo.append(", ").append("World"); // Hello, World
demo.insert(5, " Java"); // Hello Java, World
demo.delete(5, 10); // Hello, World
demo.reverse(); // dlroW ,olleH
System.out.println(demo);
// Capacity management (optional optimisation)
StringBuilder sb2 = new StringBuilder(256); // pre-allocate buffer
sb2.append("Pre-allocated for performance");
System.out.println(sb2.capacity()); // at least 256
}
}Key Points to Remember
- Strings are immutable — every modification creates a new String object; the original is unchanged
- String literals share pooled instances; new String() bypasses the pool — always compare with .equals()
- Use StringBuilder (not +) in loops to avoid O(n²) concatenation cost
- strip() (Java 11+) is Unicode-aware; prefer it over trim() for modern code
- isBlank() (Java 11+) returns true for empty strings AND strings containing only whitespace
- substring(start, end) — end index is exclusive; substring(7, 11) gives 4 characters
Practice Strings & StringBuilder in the Playground
Run and modify code directly in your browser - no setup needed.
Interview Questions
Sign in to ask AriaWhy is String immutable in Java? What are the benefits?
What is the String pool? How does string interning work?
What is the difference between StringBuilder and StringBuffer?
Why should you not use == to compare Strings in Java?
Reverse a String without using StringBuilder.reverse()
Ask Aria about Strings & StringBuilder
Your personal AI tutor — ask anything about this concept