Skip to main content

    Lesson 8 • Intermediate

    Java Strings

    Strings are the most commonly used type in real-world Java. Every user input, every file name, every database query, every error message — they're all strings. In this lesson, you'll learn to search, compare, split, format, and efficiently build strings. You'll also learn the #1 Java gotcha: why == doesn't work for comparing strings.

    What You'll Learn

    • ✅ Creating strings and concatenation
    • ✅ Immutability — why strings can never be changed
    • ✅ The String Pool — how Java saves memory with string reuse
    • ✅ Essential methods: length, charAt, substring, indexOf, contains
    • ✅ Comparing strings with .equals() vs == (critical!)
    • ✅ Transforming: toUpperCase, replace, trim, split, join
    • ✅ StringBuilder — efficient string building in loops
    • ✅ String.format() — clean formatted output

    💡 Real-World Analogy

    A String is like a necklace of letter beads. Each bead is a character, and you can examine them, count them, or create a new necklace — but you can never change the beads on an existing necklace. Every "change" actually creates a brand new necklace. This is called immutability.

    1️⃣ Creating Strings & Concatenation

    You create strings by wrapping text in double quotes. You can combine strings using the + operator (concatenation):

    // Creating strings
    String name = "Alice";
    String greeting = "Hello, World!";
    
    // Concatenation — joining strings together
    String message = "Hello, " + name + "!";
    // → "Hello, Alice!"
    
    // Concatenating different types (auto-converted to String)
    int age = 25;
    String info = name + " is " + age + " years old";
    // → "Alice is 25 years old"
    
    // ⚠️ Watch out for order of operations!
    System.out.println("Score: " + 5 + 3);   // "Score: 53" (strings!)
    System.out.println("Score: " + (5 + 3));  // "Score: 8"  (math first)

    2️⃣ Immutability & The String Pool

    Immutability means once a String is created, it can never be changed. Every method that seems to "modify" a string actually creates a brand new string and returns it. The original is untouched.

    String name = "Alice";
    name.toUpperCase();         // Creates "ALICE" but we don't store it!
    System.out.println(name);   // Still "Alice" — original unchanged!
    
    name = name.toUpperCase();  // ✅ Now name points to "ALICE"
    System.out.println(name);   // "ALICE"

    Java also maintains a String Pool — a special memory area that reuses identical string literals:

    String a = "Hello";              // Goes to String Pool
    String b = "Hello";              // Reuses same object!
    String c = new String("Hello");  // Forces NEW object (bypasses pool)
    
    a == b     // true  (same pool object)
    a == c     // false (different objects!)
    a.equals(c) // true  (same content ✓)

    🔑 This is why == is unreliable for strings! It compares memory addresses, not content. Two strings can have identical text but be different objects in memory. Always use .equals().

    3️⃣ Essential String Methods

    These are the methods you'll use every day. Memorize these and you'll handle 90% of string tasks:

    String text = "Hello, World!";
    
    // === INSPECTING ===
    text.length()              // 13 (number of characters)
    text.charAt(0)             // 'H' (first character)
    text.charAt(6)             // 'W' 
    text.isEmpty()             // false
    text.isBlank()             // false (Java 11+, checks whitespace too)
    
    // === SEARCHING ===
    text.contains("World")     // true
    text.indexOf("World")      // 7 (position where "World" starts)
    text.indexOf("xyz")        // -1 (not found)
    text.lastIndexOf("l")      // 10 (last occurrence)
    text.startsWith("Hello")   // true
    text.endsWith("!")          // true
    
    // === TRANSFORMING (returns NEW string!) ===
    text.toUpperCase()         // "HELLO, WORLD!"
    text.toLowerCase()         // "hello, world!"
    text.substring(0, 5)       // "Hello" (from index 0 to 4)
    text.substring(7)          // "World!" (from index 7 to end)
    text.replace("World", "Java") // "Hello, Java!"
    "  spaces  ".trim()        // "spaces"
    
    // === SPLITTING & JOINING ===
    "a,b,c".split(",")        // String[] {"a", "b", "c"}
    String.join(" - ", "a", "b", "c")  // "a - b - c"
    Try It: String Methods
    public class Main {
        public static void main(String[] args) {
            String text = "Hello, World!";
            System.out.println("Text: '" + text + "'");
    
            // 1. Inspecting
            System.out.println("\n1. INSPECTING:");
            System.out.println("   length: " + text.length());
            System.out.println("   charAt(0): '" + text.charAt(0) + "'");
            System.out.println("   charAt(7): '" + text.charAt(7) + "'");
    
            // 2. Searching
            System.out.println("\n2. SEARCHING:");
            System.out.println("   contains 'World': " + text.contains("World"));
            System.out.println("   indexOf 'World': " + text.indexOf("World"));
            System.out.println("   indexOf 'xyz': " + text.indexOf("xyz") + " (-1 = not found)");
            System.out.println("   startsWith 'Hello': " + text.startsWith("Hello"));
            System.out.println("   endsWith '!': " + text.endsWith("!"));
    
            // 3. Transforming (returns a NEW string)
            System.out.println("\n3. TRANSFORMING:");
            System.out.println("   toUpperCase: " + text.toUpperCase());
            System.out.println("   toLowerCase: " + text.toLowerCase());
            System.out.println("   substring(0,5): " + text.substring(0, 5));
            System.out.println("   substring(7): " + text.substring(7));
            System.out.println("   replace: " + text.replace("World", "Java"));
    
            // 4. Trim
            System.out.println("\n4. TRIM:");
            String padded = "   Hello   ";
            System.out.println("   Before: '" + padded + "'");
            System.out.println("   After:  '" + padded.trim() + "'");
    
            // 5. Split and Join
            System.out.println("\n5. SPLIT & JOIN:");
            String csv = "Java,Python,JavaScript,C++";
            String[] langs = csv.split(",");
            System.out.println("   Split length: " + langs.length);
            System.out.println("   Join: " + String.join(" | ", langs));
    
            // 6. Comparison (.equals vs ==)
            System.out.println("\n6. COMPARISON (equals vs ==):");
            String s1 = "Hello";
            String s2 = "Hello";
            String s3 = "hello";
            System.out.println("   s1.equals(s2): " + s1.equals(s2) + " (same content)");
            System.out.println("   s1.equals(s3): " + s1.equals(s3) + " (case differs!)");
            System.out.println("   equalsIgnoreCase: " + s1.equalsIgnoreCase(s3));
    
            System.out.println("\nAlways use .equals() in Java, never == for strings!");
        }
    }
    Output
    Text: 'Hello, World!'
    
    1. INSPECTING:
       length: 13
       charAt(0): 'H'
       charAt(7): 'W'
    
    2. SEARCHING:
       contains 'World': true
       indexOf 'World': 7
       indexOf 'xyz': -1 (-1 = not found)
       startsWith 'Hello': true
       endsWith '!': true
    
    3. TRANSFORMING:
       toUpperCase: HELLO, WORLD!
       toLowerCase: hello, world!
       substring(0,5): Hello
       substring(7): World!
       replace: Hello, Java!
    
    4. TRIM:
       Before: '   Hello   '
       After:  'Hello'
    
    5. SPLIT & JOIN:
       Split length: 4
       Join: Java | Python | JavaScript | C++
    
    6. COMPARISON (equals vs ==):
       s1.equals(s2): true (same content)
       s1.equals(s3): false (case differs!)
       equalsIgnoreCase: true
    
    Always use .equals() in Java, never == for strings!
    This is real code — run it for free atonecompiler.com/javaor in your own editor.

    4️⃣ String Comparison — The #1 Java Gotcha

    This is the single most common bug Java beginners make. Let's be absolutely clear about it:

    // ❌ WRONG — compares memory addresses, not content!
    String input = scanner.nextLine();  // user types "yes"
    if (input == "yes") { ... }  // MIGHT work, might not! Unreliable!
    
    // ✅ CORRECT — compares actual text content
    if (input.equals("yes")) { ... }
    
    // ✅ Case-insensitive comparison
    if (input.equalsIgnoreCase("YES")) { ... }
    
    // ✅ Null-safe trick — put the constant first
    if ("yes".equals(input)) { ... }  // Won't crash even if input is null!
    
    // ❌ CRASH if input is null
    if (input.equals("yes")) { ... }  // NullPointerException!

    🔑 The rule: == checks "are these the exact same object in memory?" .equals() checks "do these contain the same text?" You almost always want .equals().

    5️⃣ StringBuilder — Efficient String Building

    Because strings are immutable, concatenation in a loop creates a new string object every iteration. For large loops, this wastes massive amounts of memory. Use StringBuilder instead:

    // ❌ SLOW — creates 1000 temporary String objects!
    String result = "";
    for (int i = 0; i < 1000; i++) {
        result += i + ", ";  // New String EVERY time
    }
    
    // ✅ FAST — uses one mutable buffer
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 1000; i++) {
        sb.append(i).append(", ");
    }
    String result = sb.toString();
    
    // StringBuilder methods:
    sb.append("text");      // Add to end
    sb.insert(0, "start");  // Insert at position
    sb.delete(0, 5);        // Remove characters
    sb.reverse();            // Reverse the content
    sb.length();             // Current length
    sb.toString();           // Convert to String

    💡 Rule of thumb: If you're concatenating in a loop, use StringBuilder. For a few simple concatenations outside loops, regular + is fine.

    6️⃣ String.format() — Clean Formatted Output

    Instead of ugly concatenation with lots of + signs, use String.format() for readable, clean string construction:

    String name = "Alice";
    int age = 30;
    double gpa = 3.857;
    
    // ❌ Hard to read with concatenation
    String msg1 = "Name: " + name + ", Age: " + age + ", GPA: " + gpa;
    
    // ✅ Clean with String.format()
    String msg2 = String.format("Name: %s, Age: %d, GPA: %.1f", name, age, gpa);
    // → "Name: Alice, Age: 30, GPA: 3.9"
    
    // Format specifiers:
    // %s  = String
    // %d  = integer
    // %f  = floating-point
    // %.2f = 2 decimal places
    // %n  = newline
    // %10s = right-padded to 10 chars
    // %-10s = left-padded to 10 chars
    Try It: StringBuilder & Formatting
    public class Main {
        public static void main(String[] args) {
            // 1. StringBuilder in a loop
            System.out.println("1. STRING BUILDING IN A LOOP:");
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i <= 10; i++) {
                sb.append("Item").append(i);
                if (i < 10) sb.append(", ");
            }
            System.out.println("   " + sb);
    
            // 2. Formatted output with String.format / printf
            System.out.println("\n2. FORMATTED OUTPUT:");
            String[] names = {"Alice", "Bob", "Charlie"};
            int[] ages = {20, 22, 19};
            double[] gpas = {3.85, 3.42, 3.91};
            System.out.printf("   %-10s%-5s%s%n", "Name", "Age", "GPA");
            System.out.println("   --------------------");
            for (int i = 0; i < names.length; i++) {
                System.out.printf("   %-10s%-5d%.2f%n", names[i], ages[i], gpas[i]);
            }
    
            // 3. Null-safe comparison (constant first)
            System.out.println("\n3. NULL-SAFE COMPARISON:");
            String input = null;
            // input.equals("yes") would throw NullPointerException!
            // "yes".equals(input) returns false safely.
            System.out.println("   \"yes\".equals(input): " + "yes".equals(input) + " (safe, no crash)");
    
            // 4. Building a report
            System.out.println("\n4. BUILDING A REPORT:");
            int[] scores = {85, 92, 78, 95, 88};
            int total = 0, max = scores[0], min = scores[0];
            for (int s : scores) {
                total += s;
                if (s > max) max = s;
                if (s < min) min = s;
            }
            double avg = total / (double) scores.length;
            StringBuilder report = new StringBuilder();
            report.append("=== Score Report ===\n");
            report.append("Students: ").append(scores.length).append("\n");
            report.append("Total:    ").append(total).append("\n");
            report.append(String.format("Average:  %.1f%n", avg));
            report.append("Highest:  ").append(max).append("\n");
            report.append("Lowest:   ").append(min).append("\n");
            report.append("Range:    ").append(max - min);
            System.out.println(report);
    
            System.out.println("\nStringBuilder for loops, String.format() for clean output!");
        }
    }
    Output
    1. STRING BUILDING IN A LOOP:
       Item1, Item2, Item3, Item4, Item5, Item6, Item7, Item8, Item9, Item10
    
    2. FORMATTED OUTPUT:
       Name      Age  GPA
       --------------------
       Alice     20   3.85
       Bob       22   3.42
       Charlie   19   3.91
    
    3. NULL-SAFE COMPARISON:
       "yes".equals(input): false (safe, no crash)
    
    4. BUILDING A REPORT:
    === Score Report ===
    Students: 5
    Total:    438
    Average:  87.6
    Highest:  95
    Lowest:   78
    Range:    17
    
    StringBuilder for loops, String.format() for clean output!
    This is real code — run it for free atonecompiler.com/javaor in your own editor.

    7️⃣ Real-World String Patterns

    Here are patterns you'll use constantly in real Java applications:

    // Email validation (basic)
    boolean validEmail = email.contains("@") && email.contains(".");
    
    // File extension check
    if (filename.endsWith(".java")) { ... }
    if (filename.endsWith(".pdf") || filename.endsWith(".doc")) { ... }
    
    // Parsing CSV data
    String line = "Alice,25,3.85";
    String[] parts = line.split(",");
    String name = parts[0];        // "Alice"
    int age = Integer.parseInt(parts[1]);  // 25
    double gpa = Double.parseDouble(parts[2]); // 3.85
    
    // Creating URL slugs
    String slug = title.toLowerCase()
        .replaceAll("[^a-z0-9]+", "-")  // Replace non-alphanumeric
        .replaceAll("^-|-$", "");        // Remove leading/trailing dashes
    
    // Sanitizing user input
    String clean = input.trim()             // Remove leading/trailing spaces
        .replaceAll("\\s+", " ");        // Collapse multiple spaces
    Try It: Real-World String Problems
    public class Main {
        static boolean isPalindrome(String str) {
            String clean = str.toLowerCase().replaceAll("[^a-z0-9]", "");
            return clean.equals(new StringBuilder(clean).reverse().toString());
        }
    
        static boolean isValidEmail(String email) {
            int at = email.indexOf("@");
            return email.contains("@") && email.contains(".")
                    && at > 0 && email.lastIndexOf(".") > at;
        }
    
        public static void main(String[] args) {
            // 1. Palindrome checker
            System.out.println("1. PALINDROME CHECKER:");
            String[] words = {"racecar", "hello", "A man a plan a canal Panama", "level", "world"};
            for (String w : words) {
                System.out.println("   '" + w + "' -> " + (isPalindrome(w) ? "Palindrome!" : "Not a palindrome"));
            }
    
            // 2. Email validator
            System.out.println("\n2. EMAIL VALIDATOR:");
            String[] emails = {"alice@gmail.com", "bob@", "@invalid", "test@site.org", "noatsign"};
            for (String e : emails) {
                System.out.printf("   %-20s%s%n", e, isValidEmail(e) ? "Valid" : "Invalid");
            }
    
            // 3. CSV parser
            System.out.println("\n3. CSV PARSER:");
            String csvData = "Alice,25,3.85\nBob,22,3.42\nCharlie,19,3.91";
            String[] rows = csvData.split("\n");
            System.out.printf("   %-10s%-5s%s%n", "Name", "Age", "GPA");
            System.out.println("   --------------------");
            for (String row : rows) {
                String[] cols = row.split(",");
                System.out.printf("   %-10s%-5s%.2f%n", cols[0], cols[1], Double.parseDouble(cols[2]));
            }
    
            // 4. URL slug generator
            System.out.println("\n4. URL SLUG GENERATOR:");
            String[] titles = {"Hello World!", "Java Programming 101", "How to Learn Fast & Easy"};
            for (String t : titles) {
                String slug = t.toLowerCase().replaceAll("[^a-z0-9]+", "-").replaceAll("^-|-$", "");
                System.out.println("   '" + t + "' -> /" + slug);
            }
    
            // 5. Character counter
            System.out.println("\n5. CHARACTER COUNTER:");
            String text = "Hello World";
            int vowels = 0, consonants = 0, spaces = 0;
            for (char ch : text.toLowerCase().toCharArray()) {
                if ("aeiou".indexOf(ch) >= 0) vowels++;
                else if (ch == ' ') spaces++;
                else if (ch >= 'a' && ch <= 'z') consonants++;
            }
            System.out.println("   Text: '" + text + "'");
            System.out.println("   Vowels: " + vowels + ", Consonants: " + consonants + ", Spaces: " + spaces);
    
            System.out.println("\nStrings are IMMUTABLE - every operation creates a new one!");
        }
    }
    Output
    1. PALINDROME CHECKER:
       'racecar' -> Palindrome!
       'hello' -> Not a palindrome
       'A man a plan a canal Panama' -> Palindrome!
       'level' -> Palindrome!
       'world' -> Not a palindrome
    
    2. EMAIL VALIDATOR:
       alice@gmail.com     Valid
       bob@                Invalid
       @invalid            Invalid
       test@site.org       Valid
       noatsign            Invalid
    
    3. CSV PARSER:
       Name      Age  GPA
       --------------------
       Alice     25   3.85
       Bob       22   3.42
       Charlie   19   3.91
    
    4. URL SLUG GENERATOR:
       'Hello World!' -> /hello-world
       'Java Programming 101' -> /java-programming-101
       'How to Learn Fast & Easy' -> /how-to-learn-fast-easy
    
    5. CHARACTER COUNTER:
       Text: 'Hello World'
       Vowels: 3, Consonants: 7, Spaces: 1
    
    Strings are IMMUTABLE - every operation creates a new one!
    This is real code — run it for free atonecompiler.com/javaor in your own editor.

    Common Mistakes

    • ❌ Using == instead of .equals():
      if (name == "Alice")       // ❌ Compares memory addresses
      if (name.equals("Alice"))  // ✅ Compares text content
    • ❌ Forgetting strings are immutable:
      name.toUpperCase();        // ❌ Result thrown away!
      name = name.toUpperCase(); // ✅ Store the new string
    • ❌ Calling methods on null: null.length() crashes with NullPointerException. Always check for null first, or use the constant-first pattern: "expected".equals(input).
    • ❌ Concatenation in loops: Creates thousands of temporary objects. Use StringBuilder instead.
    • ❌ Confusing length vs length(): Arrays: arr.length (property). Strings: str.length() (method with parentheses).

    Pro Tips

    💡 Use .equalsIgnoreCase() for user input — users might type "YES", "Yes", or "yes".

    💡 Use .strip() instead of .trim() (Java 11+) — it handles Unicode whitespace properly.

    💡 Use String.format() for readable string construction instead of chaining + operators.

    💡 Java 15+ text blocks: Use """multi-line text""" for SQL queries, HTML, and JSON.

    💡 String.join() is your friend: String.join(", ", list) is cleaner than manual loops.

    📋 Quick Reference

    MethodExampleResult
    length()"Hello".length()5
    charAt(i)"Hello".charAt(1)'e'
    equals()"Hi".equals("Hi")true
    substring(a,b)"Hello".substring(0,3)"Hel"
    indexOf()"Hello".indexOf("ll")2
    split()"a,b".split(",")["a","b"]
    replace()"Hi".replace("H","B")"Bi"
    trim()" Hi ".trim()"Hi"
    format()String.format("%s=%d","x",5)"x=5"

    🎉 Lesson Complete!

    You now know how to create, compare, search, split, format, and efficiently build strings in Java! Strings appear in virtually every Java program — from parsing user input to building SQL queries to formatting log messages.

    Next up: Object-Oriented Programming — learn to design classes and objects, the foundation of all Java applications.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service

    Install LearnCodingFast

    Learn faster with the app on your home screen.