Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • About
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

Β© 2026 Chaturmind. All rights reserved.

πŸ‘₯10,106visitors

Built for engineers who want to go deep.


← Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
Chaturmind
← Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
HomeLearnJavaJava Core FundamentalsExceptions & Best Practices
βœ“ FreeBeginnerΒ· 7 min read

String Manipulation

Immutability, StringBuilder, common String methods, and interview patterns.

Published September 21, 2026


String Manipulation

String is probably the most-used class in Java, and it behaves differently from most objects in ways that cause real bugs: comparing with ==, building strings in loops, split surprises, and mixing up bytes and characters. This lesson covers how strings actually work and the handful of rules that prevent those bugs.

Advertisement

Strings are immutable

A String object can never change after it's created. Every "modifying" method returns a new string:

String s = "hello";
s.toUpperCase();            // returns "HELLO" β€” and the result is thrown away
System.out.println(s);      // still "hello"

s = s.toUpperCase();        // reassign the variable to the new string

Why Java designed it this way:

  • Safe sharing: many variables can point at the same string with no risk of one changing it for the others.
  • Thread safety for free: immutable objects need no synchronization.
  • Reliable hash keys: a String's hash code is computed once and cached, and can never go stale, which is why strings are ideal HashMap keys.
  • Security: a file path or class name checked by a security manager can't be altered after the check.

The string pool, and why == is a trap

String literals are stored once in a shared string pool, so identical literals refer to the same object:

String a = "java";
String b = "java";
String c = new String("java");      // forces a new, separate object
String d = "ja" + "va";             // compile-time constant β†’ also pooled

a == b;          // true  β€” same pooled object
a == d;          // true  β€” the compiler folded the constant
a == c;          // false β€” different objects with the same content
a.equals(c);     // true  β€” same characters

== compares references (is it the same object?). .equals() compares content. Code that uses == often seems to work, because literals happen to be pooled, and then fails when a string comes from user input, a database or a concatenation at runtime. Always compare strings with equals (or equalsIgnoreCase). Use Objects.equals(a, b) when either may be null, or put the literal first: "admin".equals(role) can't throw an NPE.

intern() returns the pooled copy of a string. It's rarely needed in application code.

Building strings: StringBuilder

// ❌ Quadratic: each += copies the whole string built so far
String csv = "";
for (String item : items) csv += item + ",";

// βœ… Linear: one growable buffer
StringBuilder sb = new StringBuilder();
for (String item : items) sb.append(item).append(',');
String csv = sb.toString();

With 10,000 items, the first version copies about 50 million characters in total, and the second copies each character once. Note that a single expression like "Hello " + name + "!" is fine: the compiler optimizes that (via StringBuilder, or invokedynamic string concatenation since Java 9). The problem is only concatenation inside loops.

Even simpler for joining: String.join(",", items) or items.stream().collect(Collectors.joining(",")).

StringBuffer is the older, synchronized version of StringBuilder. You almost never need it: a builder is normally used by one thread.

The methods you'll use constantly

String s = "  Hello, World  ";

s.length();                 // 16
s.charAt(2);                // 'H'
s.indexOf("World");         // 9   (-1 if absent)
s.contains("lo, W");        // true
s.substring(2, 7);          // "Hello"  β€” end index is exclusive
s.strip();                  // "Hello, World"  (Unicode-aware; trim() only removes chars ≀ ' ')
s.isBlank();                // false  (true for "", "   ", tabs…) β€” Java 11
s.toLowerCase(Locale.ROOT); // pass a Locale for machine text (see below)
s.replace("l", "L");        // literal replacement, all occurrences
s.replaceAll("\\s+", " ");  // REGEX replacement
s.startsWith("  He");       // true
"ab".repeat(3);             // "ababab" β€” Java 11
"a\nb".lines().toList();    // ["a", "b"] β€” Java 11
String.valueOf(42);         // "42" (and String.valueOf(null object) gives "null", no NPE)

split surprises

"a,b,,c,,".split(",");     // ["a", "b", "", "c"]  β€” trailing empty strings are dropped!
"a,b,,c,,".split(",", -1); // ["a", "b", "", "c", "", ""] β€” keep them with a negative limit
"1.2.3".split(".");        // []  β€” the argument is a REGEX, and "." matches everything
"1.2.3".split("\\.");      // ["1", "2", "3"]

When parsing real formats such as CSV, use a proper parser. Quoted fields containing commas break naive splitting.

Locale and case conversion

toUpperCase() and toLowerCase() without arguments use the machine's default locale. In Turkish, "TITLE".toLowerCase() produces a dotless Δ±, which famously breaks comparisons of keywords, file names and protocol headers. For text that isn't shown to humans, use toLowerCase(Locale.ROOT), or compare with equalsIgnoreCase.

Characters vs bytes

A Java String is a sequence of UTF-16 chars. Most characters take one char, but emoji and some rare scripts take two (a surrogate pair). So "πŸ‘".length() is 2. charAt can return half an emoji, and reversing a string char by char can corrupt it. When correctness matters, work with code points (s.codePoints(), s.codePointCount(...)).

When converting to bytes (files, network, hashing), always name the charset: s.getBytes(StandardCharsets.UTF_8) and new String(bytes, StandardCharsets.UTF_8). The no-argument versions use the platform default and produce different results on different machines. (Since Java 18 the default is UTF-8, but explicit is still clearer.)

Formatting and text blocks

String msg = "Order %s: %d items, total %.2f".formatted(id, count, total);   // Java 15; same as String.format

String json = """
        {
          "id": "%s",
          "items": %d
        }
        """.formatted(id, count);      // text block: multi-line literal, indentation stripped

Memory: compact strings

Since Java 9, strings containing only Latin-1 characters store one byte per character instead of two (compact strings), which roughly halves memory for typical English text. It's automatic and needs no code changes, but it's worth knowing when estimating memory use.

Common interview-style operations

// Reverse (fine for plain text; use code points for emoji-safe reversal)
String reversed = new StringBuilder(s).reverse().toString();

// Palindrome check without extra memory
boolean isPalindrome(String s) {
    for (int i = 0, j = s.length() - 1; i < j; i++, j--)
        if (s.charAt(i) != s.charAt(j)) return false;
    return true;
}

// Character frequency (letters a–z)
int[] freq = new int[26];
for (char ch : s.toCharArray()) if (ch >= 'a' && ch <= 'z') freq[ch - 'a']++;

Follow-up questions this topic invites β€” and their answers

Q: Why is String immutable? A: It allows safe sharing and pooling of literals, makes strings thread-safe without locks, lets the hash code be cached (important for HashMap keys), and protects security-sensitive values like file paths and class names from being changed after validation.

Q: How many objects does new String("hello") create? A: Up to two: the literal "hello" in the string pool (if it isn't already there, created when the class loads), plus a new String object on the heap from new. That's why new String(literal) is almost always pointless.

Q: Is + concatenation always slow? A: No. Within a single expression, the compiler generates efficient code, and constant expressions are folded at compile time. It's only repeated += inside a loop that's O(nΒ²), because each step creates a new string and copies everything so far. Use StringBuilder there.

Q: Why can "πŸ˜€".length() return 2? A: length() counts UTF-16 code units. Characters outside the Basic Multilingual Plane, including most emoji, are encoded as two code units (a surrogate pair). Use codePointCount or codePoints() to count or iterate over real characters.

Q: What's the difference between trim() and strip()? A: trim() removes characters with code ≀ U+0020 (ASCII space and control characters). strip() (Java 11) removes all Unicode whitespace, such as the non-breaking and ideographic spaces often pasted from other apps. Prefer strip, stripLeading, stripTrailing and isBlank in modern code.

Advertisement

Previous

equals() and hashCode()

Next

JVM Memory Areas

AI Tutor

Lesson: String Manipulation

Quick actions

AI responses can be inaccurate. Verify critical information.