Notifications

No notifications

/Phase 2

Strings & StringBuilder

The String Class šŸ”¤

String is the most-used class in Java. Two crucial facts:

1. Strings are immutable. Every "modification" returns a new String. 2. Compare with .equals() — never ==.

String name = "Asha";

int len = name.length(); // 4 char first = name.charAt(0); // 'A' String upper = name.toUpperCase(); // "ASHA" (new string) String slice = name.substring(1, 3); // "sh" boolean has = name.contains("sh"); // true String rep = name.replace("a", "@"); // "@sh@" String trim = " hi ".strip(); // "hi" (Java 11+)

Building Strings Efficiently — StringBuilder

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i).append(',');
}
String result = sb.toString();

Concatenating strings in a loop with + is O(n²). StringBuilder is O(n).

Text Blocks (Java 15+)

String html = """
    <h1>Hello</h1>
    <p>Multi-line, no escaping.</p>
    """;

Formatting

String s1 = String.format("name=%s age=%d", "Asha", 19);
String s2 = "name=%s age=%d".formatted("Asha", 19);   // Java 15+

On this page

Detailed Theory

Why Strings Are Immutable

Once a String is built, you can never change its characters. s.toUpperCase() doesn't modify s — it returns a brand-new String.

Reasons for the design

  • Thread safety: shareable across threads with no locking.
  • Hashing: hashCode() is cached on first call.
  • String pool: literal strings are interned and shared, saving memory.
  • Security: passed to system calls (file paths, SQL, network) without fear of mid-call mutation.
String s = "hello";
s.toUpperCase();         // returns "HELLO" but discarded
System.out.println(s);   // still "hello"

s = s.toUpperCase(); // assign back to keep

Equality — Always .equals()

String a = "hi";
String b = "hi";
String c = new String("hi");

a == b // true (both interned literals — same object) a == c // false (new String makes a new object) a.equals(c) // true (same content) a.equalsIgnoreCase("HI") // true

> Use Objects.equals(x, y) if either side might be null — it handles null == null for you.

The Most-Used Methods

String s = "Hello, Java!";

s.length(); // 12 s.charAt(7); // 'J' s.indexOf("Java"); // 7 s.indexOf('z'); // -1 (not found) s.lastIndexOf('l'); // 3 s.substring(7); // "Java!" s.substring(7, 11); // "Java" s.toLowerCase(); // "hello, java!" s.toUpperCase(); // "HELLO, JAVA!" s.replace('l', 'L'); // "HeLLo, Java!" s.replace("Java", "World"); // "Hello, World!" s.contains("Java"); // true s.startsWith("Hello"); // true s.endsWith("!"); // true s.trim(); // strips ASCII whitespace s.strip(); // strips Unicode whitespace (Java 11+) s.isEmpty(); // false (length == 0) s.isBlank(); // false (only whitespace) (Java 11+)

Splitting & Joining

String csv = "a,b,c,d";
String[] parts = csv.split(",");        // {"a","b","c","d"}

// limit: stop after N tokens "a,b,c,d".split(",", 2); // {"a", "b,c,d"}

// regex split "one two three".split("\\s+"); // {"one","two","three"}

// join String joined = String.join("

", "a", "b", "c"); // "ab
c" String fromList = String.join(",", List.of("x","y")); // "x,y"

> split takes a regex, not a literal. Use Pattern.quote(".") or split("\\.") to split on a literal period.

String ↔ char[]

char[] chars = "hi".toCharArray();      // {'h', 'i'}
String back  = new String(chars);       // "hi"
String back2 = String.valueOf(chars);   // "hi"

Comparison & Sorting

"apple".compareTo("banana");             // negative (a < b)
"apple".compareToIgnoreCase("APPLE");    // 0

List<String> names = new ArrayList<>(List.of("Mia", "Asha", "Bishan")); Collections.sort(names); // alphabetical names.sort(String.CASE_INSENSITIVE_ORDER);

StringBuilder — When You Need Speed

Strings are immutable, so:

String s = "";
for (int i = 0; i < 10_000; i++) {
    s = s + i;        // creates 10,000 new strings — O(n²)
}

Use StringBuilder instead:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10_000; i++) {
    sb.append(i);     // mutates in place — O(n)
}
String result = sb.toString();

StringBuilder API

StringBuilder sb = new StringBuilder("Hello");
sb.append(", ").append("world").append('!');     // chainable
sb.insert(0, ">>> ");                            // ">>> Hello, world!"
sb.delete(0, 4);                                  // "Hello, world!"
sb.deleteCharAt(0);                               // "ello, world!"
sb.reverse();                                     // "!dlrow ,olle"
sb.length();
sb.toString();

> Need a thread-safe variant? Use StringBuffer (synchronized, slower). 99% of the time StringBuilder is the right pick.

Text Blocks (Java 15+)

String json = """
    {
      "name": "Asha",
      "age":  19
    }
    """;

String sql = """ SELECT id, name FROM users WHERE active = true """;

  • Triple-quoted, multi-line.
  • Common leading indentation is stripped.
  • \n, \t work; " doesn't need escaping.
  • Trailing \ joins to next line without newline.

Formatting

String.format("%-10s %5d", "Asha", 19);             // "Asha            19"
"%-10s %5d".formatted("Asha", 19);                  // Java 15+ instance method
String.format("%.3f", Math.PI);                     // "3.142"

Regex Quick Hits

"hello123".matches("[a-z]+\\d+");                // true
"a-b-c".replaceAll("-", "/");                       // "a/b/c"
"a1b22c".split("\\d+");                           // {"a","b","c"}

For complex regex, use Pattern + Matcher directly.

String ↔ Number

int    n = Integer.parseInt("42");
double d = Double.parseDouble("3.14");
String s = String.valueOf(42);              // "42"
String b = Integer.toString(42, 2);         // "101010" (radix)

Integer.parseInt throws NumberFormatException on bad input — wrap in try/catch or validate first.

Performance Notes

  • String literals are interned in a JVM-wide pool. Two "hi" literals are the SAME object.
  • new String("hi") forces a new object — almost never what you want.
  • Use StringBuilder in loops; modern javac already converts simple a + b + c (no loop) to StringBuilder calls automatically.
  • For very high-throughput logging, use String.format sparingly — it's slower than concat.

Cheat-Sheet

NeedCode
Lengths.length()
Get chars.charAt(i)
Substrings.substring(a, b)
Splits.split(regex)
JoinString.join(",", parts)
Equalitya.equals(b)
Case-insensitive eqa.equalsIgnoreCase(b)
Trims.strip() (Java 11+)
Containss.contains(sub)
Replaces.replace(old, new)
FormatString.format(fmt, ...) or fmt.formatted(...)
Build in loopStringBuilder
Multi-linetext block """

You can now wrangle text efficiently. Next: arrays — Java's fixed-size containers.