LearnFrenzy
Sign in Take a free test

Strings · Lesson 15 of 42

Strings and the String Pool

5 min read Updated Nov 7, 2026 Saurabh Samir

Almost every program handles text – names, emails, JSON, log lines. In Java text is represented by the String class, which has two properties you must understand: strings are immutable, and literal strings are stored in a shared string pool. Both come up in nearly every Java interview.

In this lesson

  • Creating strings, immutability and the string pool
  • == vs equals() once and for all
  • The String methods you will use every day
  • Splitting, joining, text blocks and formatting

Strings are immutable

Once a String object exists, its characters never change. Methods that seem to modify a string actually return a new one:

public class Main {
    public static void main(String[] args) {
        String name = "kavya";
        name.toUpperCase();                 // result thrown away!
        System.out.println(name);
        name = name.toUpperCase();          // keep the new string
        System.out.println(name);
        String full = name.concat(" RAO");
        System.out.println(full + " | " + name);
    }
}

Output

kavya
KAVYA
KAVYA RAO | KAVYA

Why immutable?

Immutability makes strings safe to share between threads, safe as HashMap keys (their hash code can be cached), and secure for things like file paths and database URLs, which can't be changed after a security check. It also makes the string pool possible.

The string pool

String literals are stored once in a special area of the heap called the string pool. Two identical literals share the same object; new String(...) always creates a separate object.

public class Main {
    public static void main(String[] args) {
        String a = "learn";
        String b = "learn";
        String c = new String("learn");
        String d = c.intern();          // the pooled version
        System.out.println(a == b);       // same pooled object
        System.out.println(a == c);       // different objects
        System.out.println(a.equals(c));  // same text
        System.out.println(a == d);
    }
}

Output

true
false
true
true

Where each reference points

  • a→ "learn" (pool)literal
  • b→ same pooled objecta == b is true
  • c→ new "learn" (heap)a == c is false
  • d→ pooled objectc.intern()

Rule: compare strings with equals()

== compares references, so it depends on how the strings were created. Text from input, files or databases is never pooled automatically. Use a.equals(b), a.equalsIgnoreCase(b), or "constant".equals(variable), which can't throw a NullPointerException.

Essential String methods

public class Main {
    public static void main(String[] args) {
        String s = "  Learn Java at LearnFrenzy  ";
        String t = s.trim();
        System.out.println("[" + t + "] length " + t.length());
        System.out.println(t.charAt(0) + " " + t.indexOf("Java") + " " + t.lastIndexOf("Learn"));
        System.out.println(t.substring(6, 10));          // from 6 up to (not incl.) 10
        System.out.println(t.toLowerCase().contains("java"));
        System.out.println(t.startsWith("Learn") + " " + t.endsWith("Frenzy"));
        System.out.println(t.replace("Java", "Spring Boot"));
        System.out.println("ab".repeat(3) + " " + "".isEmpty() + " " + "   ".isBlank());
        System.out.println("Banana".compareTo("Apple") > 0);   // alphabetical order
    }
}

Output

[Learn Java at LearnFrenzy] length 25
L 6 14
Java
true
true true
Learn Spring Boot at LearnFrenzy
ababab true true
true

"Learn Java": substring(6, 10)

  1. L0
  2. e1
  3. a2
  4. r3
  5. n4
  6. ␣5
  7. J6
  8. a7
  9. v8
  10. a9

substring(begin, end) includes begin and excludes end → "Java"

MethodReturns
length(), charAt(i)number of chars, the char at index i
indexOf(x), contains(x)first position (−1 if absent), true/false
substring(a, b)chars from a up to b − 1
trim() / strip()without leading/trailing spaces (strip also handles Unicode spaces)
toUpperCase(), toLowerCase()case-changed copy
replace(a, b)copy with every a replaced by b
isEmpty(), isBlank()length 0 / only whitespace
compareTo(x)negative, 0 or positive (dictionary order)

Splitting and joining

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        String row = "101,Anita,Sales,52000";
        String[] parts = row.split(",");
        System.out.println(parts[1] + " works in " + parts[2]);
        System.out.println(Arrays.toString("  many   spaces here ".trim().split("\\s+")));
        System.out.println(String.join(" | ", List.of("Java", "SQL", "Git")));
        char[] letters = "java".toCharArray();
        Arrays.sort(letters);
        System.out.println(new String(letters));
    }
}

Output

Anita works in Sales
[many, spaces, here]
Java | SQL | Git
aajv

split takes a regular expression: "\\s+" means "one or more whitespace characters". To split on a literal dot, write split("\\.") – a plain "." means "any character".

Text blocks (Java 15+)

Multi-line strings – JSON, SQL, HTML – used to need \n and + everywhere. Text blocks use triple quotes and keep the layout:

public class Main {
    public static void main(String[] args) {
        String json = """
            {
              "name": "Asha",
              "skills": ["Java", "Spring"]
            }
            """;
        System.out.print(json);
        String sql = """
            SELECT name, salary
            FROM employees
            WHERE dept = '%s'
            """.formatted("IT");
        System.out.print(sql);
    }
}

Output

{
  "name": "Asha",
  "skills": ["Java", "Spring"]
}
SELECT name, salary
FROM employees
WHERE dept = 'IT'

The common leading indentation is removed automatically, based on the closing """.

Formatting

public class Main {
    public static void main(String[] args) {
        String name = "Kabir";
        double amount = 2499.5;
        System.out.println(String.format("Dear %s, your bill is ₹%,.2f", name, amount));
        System.out.println("Order #%05d shipped".formatted(42));
    }
}

Output

Dear Kabir, your bill is ₹2,499.50
Order #00042 shipped

Practice

Try it yourself

  1. Check whether "Madam" is a palindrome, ignoring case.

    Show solution
    public class Main {
        public static void main(String[] args) {
            String s = "Madam".toLowerCase();
            boolean palindrome = true;
            for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
                if (s.charAt(i) != s.charAt(j)) { palindrome = false; break; }
            }
            System.out.println(palindrome);
        }
    }

    Output

    true
  2. Count the vowels in "Programming in Java".

    Show solution
    public class Main {
        public static void main(String[] args) {
            int count = 0;
            for (char c : "Programming in Java".toLowerCase().toCharArray()) {
                if ("aeiou".indexOf(c) >= 0) count++;
            }
            System.out.println(count);
        }
    }

    Output

    6
  3. Get the domain from "meera.iyer@learnfrenzy.com".

    Show solution
    public class Main {
        public static void main(String[] args) {
            String email = "meera.iyer@learnfrenzy.com";
            System.out.println(email.substring(email.indexOf('@') + 1));
        }
    }

    Output

    learnfrenzy.com

Quick check

What does "java".toUpperCase(); on its own line change?

Nothing – strings are immutable; the new string is discarded unless you assign it.

Is new String("a") == "a" true?

No. new creates a separate object; the literal is in the pool.

What is "Hello".substring(1, 3)?

"el"

Summary

  • Strings are immutable; methods return new strings.
  • Literals live in the string pool; always compare text with equals().
  • Know substring, indexOf, split, join, replace, strip; use text blocks for multi-line text.

Finished this lesson?

Mark it complete to track your progress, then carry on with the next lesson.

Next lesson

Search LearnFrenzy

Esc

Quick links