Java 2: Strings, Immutability & StringBuilder
easy⏱ 5 mincoursejava
The String Pool
String literals ("hello") are interned into a pool — duplicate literals share the same reference. new String("hello") bypasses the pool and creates a fresh object on the heap. s.intern() manually promotes a String into the pool. This is why "a" + "b" == "ab" (both compile-time constants, interned) but new String("ab") == "ab" is false.
String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b); // true (pool)
System.out.println(a == c); // false (new heap)
System.out.println(a.equals(c)); // true (value)
System.out.println(a == c.intern()); // true (promoted)
Why concatenation is quadratic
result = result + ch in a loop builds a new String each iteration, copying all previous characters. For n iterations that's O(n²) work and O(n²) garbage. StringBuilder.append(ch) amortizes to O(1) per append by growing an internal char[], giving the full loop O(n). For 100k iterations that's the difference between milliseconds and seconds.
// BAD — O(n²)
String s = "";
for (int i = 0; i < 10_000; i++) s = s + "x";
// GOOD — O(n)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10_000; i++) sb.append('x');
String result = sb.toString();
StringBuilder vs StringBuffer
StringBuilder (Java 5+): not thread-safe, fast — the default choice. StringBuffer (Java 1.0): methods are synchronized, thread-safe but slower. 99% of code wants StringBuilder; use StringBuffer only when a shared buffer is appended from multiple threads (rare — usually you'd use a queue instead).
Build a concat vs builder benchmark
Simulate both approaches. concatLoop(n) does quadratic concatenation — count the character copies (1+2+3+...+n). builderLoop(n) uses a growing buffer — count array resizes (doubling from 16). Log both totals for n=1000 and compare. You should see ~500,000 copies vs ~7 resizes.
Prefer String.format or text blocks for readable output
For complex formatted output, String.format("%-10s %5d", name, count) or Java 15+ text blocks ("""multi\nline""") beat + chains for readability. For hot paths, StringBuilder still wins on speed. Template expressions (JEP 430, preview) are the future.
Quiz: String immutability benefit
Why are Strings immutable in Java? Thread safety + hash caching + security — an immutable String can be safely shared across threads, its hashCode can be cached (computed once), and sensitive paths (classloader URLs, file paths) can't be mutated after validation.