Java Programming Strings Tutorial
50+ Methods

Java Strings - Complete Tutorial

Master Java Strings: Learn String class fundamentals, 50+ built-in methods, string manipulation, comparison, formatting, StringBuilder, StringBuffer with practical examples.

String Class

Immutable Objects

50+ Methods

Built-in Functions

StringBuilder

Mutable & Fast

StringBuffer

Thread Safe

1. Introduction to Java Strings

In Java, String is a class that represents a sequence of characters. Strings are immutable (cannot be changed once created) and are one of the most commonly used classes in Java programming.

Key Characteristics
  • Immutable: Cannot be modified after creation
  • Stored in String Pool: Memory optimization
  • Index-based: Characters accessed by index (0-based)
  • Unicode support: Supports international characters
  • Rich API: 50+ built-in methods
  • Final class: Cannot be extended
Ways to Create Strings
  • String literal: String s1 = "Hello";
  • new Keyword: String s2 = new String("Hello");
  • char array: char[] chars = {'H','e','l','l','o'}; String s3 = new String(chars);
  • byte array: byte[] bytes = {72,101,108,108,111}; String s4 = new String(bytes);
  • StringBuilder/Buffer: String s5 = new StringBuilder("Hello").toString();

String Pool Concept

Java maintains a String Pool (special memory area) to store string literals. When you create a string literal, JVM checks the pool first. If it exists, it returns the reference, otherwise creates new string.

StringCreationExample.java
public class StringCreationExample {
    public static void main(String[] args) {
        // Method 1: String literal (stored in String Pool)
        String s1 = "Hello";
        String s2 = "Hello";  // Reuses from String Pool
        
        // Method 2: Using new keyword (creates new object in heap)
        String s3 = new String("Hello");
        String s4 = new String("Hello");
        
        // Method 3: From character array
        char[] charArray = {'J', 'a', 'v', 'a'};
        String s5 = new String(charArray);
        
        // Method 4: From byte array
        byte[] byteArray = {65, 66, 67, 68};  // ASCII values
        String s6 = new String(byteArray);
        
        // Method 5: Using StringBuilder
        StringBuilder sb = new StringBuilder("Hello");
        String s7 = sb.toString();
        
        // Method 6: Using StringBuffer
        StringBuffer sbf = new StringBuffer("World");
        String s8 = sbf.toString();
        
        // Comparing strings
        System.out.println("s1 == s2: " + (s1 == s2));        // true (same reference)
        System.out.println("s1 == s3: " + (s1 == s3));        // false (different objects)
        System.out.println("s3 == s4: " + (s3 == s4));        // false (different objects)
        System.out.println("s1.equals(s3): " + s1.equals(s3)); // true (same content)
        
        System.out.println("\nString values:");
        System.out.println("s5 from char array: " + s5);      // Java
        System.out.println("s6 from byte array: " + s6);      // ABCD
        System.out.println("s7 from StringBuilder: " + s7);   // Hello
        System.out.println("s8 from StringBuffer: " + s8);    // World
        
        // Empty vs null string
        String empty = "";      // Empty string (length 0)
        String nullStr = null;  // No string object
        String space = "   ";   // String with spaces
        
        System.out.println("\nempty length: " + empty.length());        // 0
        System.out.println("space length: " + space.length());          // 3
        // System.out.println(nullStr.length());  // NullPointerException!
    }
}

2. Complete String Methods Reference

Java String class provides over 50 methods for various operations. Here's a comprehensive reference table:

Method Categories:
Length & Size Comparison Search Modification Checking Conversion
Method Category Description Return Type Example
length() Length Returns the length of the string int "Hello".length() → 5
charAt(int index) Search Returns character at specified index char "Hello".charAt(1) → 'e'
equals(Object obj) Comparison Compares string with specified object boolean "Hi".equals("Hi") → true
equalsIgnoreCase(String str) Comparison Compares ignoring case differences boolean "Hello".equalsIgnoreCase("HELLO") → true
compareTo(String str) Comparison Lexicographically compares strings int "a".compareTo("b") → -1
compareToIgnoreCase(String str) Comparison Compares strings ignoring case int "A".compareToIgnoreCase("a") → 0
startsWith(String prefix) Checking Checks if string starts with prefix boolean "Hello".startsWith("He") → true
endsWith(String suffix) Checking Checks if string ends with suffix boolean "Hello".endsWith("lo") → true
indexOf(int ch) Search Returns index of first occurrence of character int "Hello".indexOf('e') → 1
indexOf(String str) Search Returns index of first occurrence of substring int "Hello".indexOf("ll") → 2
lastIndexOf(int ch) Search Returns index of last occurrence of character int "Hello".lastIndexOf('l') → 3
substring(int beginIndex) Modification Returns substring from beginIndex to end String "Hello".substring(2) → "llo"
substring(int begin, int end) Modification Returns substring from begin to end-1 String "Hello".substring(1,4) → "ell"
concat(String str) Modification Concatenates specified string String "Hello".concat(" World") → "Hello World"
replace(char old, char new) Modification Replaces all occurrences of old char with new String "Hello".replace('l', 'p') → "Heppo"
replace(CharSequence old, CharSequence new) Modification Replaces all occurrences of substring String "Hello".replace("ll", "yy") → "Heyyo"
replaceAll(String regex, String replacement) Modification Replaces each substring matching regex String "a1b2c3".replaceAll("\\d", "") → "abc"
replaceFirst(String regex, String replacement) Modification Replaces first substring matching regex String "a1b2".replaceFirst("\\d", "") → "ab2"
toLowerCase() Conversion Converts all characters to lowercase String "Hello".toLowerCase() → "hello"
toUpperCase() Conversion Converts all characters to uppercase String "Hello".toUpperCase() → "HELLO"
trim() Modification Removes leading and trailing whitespace String " Hello ".trim() → "Hello"
strip() Modification Removes leading and trailing whitespace (Unicode-aware) String " Hello ".strip() → "Hello"
isEmpty() Checking Returns true if length is 0 boolean "".isEmpty() → true
isBlank() Checking Returns true if string is empty or contains only whitespace boolean " ".isBlank() → true
contains(CharSequence s) Checking Returns true if string contains specified sequence boolean "Hello".contains("ell") → true
split(String regex) Conversion Splits string around matches of regex String[] "a,b,c".split(",") → ["a","b","c"]
join(CharSequence delimiter, CharSequence... elements) Conversion Joins strings with specified delimiter String String.join("-", "A", "B", "C") → "A-B-C"
toCharArray() Conversion Converts string to character array char[] "Hello".toCharArray() → ['H','e','l','l','o']
getBytes() Conversion Encodes string into byte array byte[] "Hello".getBytes() → [72,101,108,108,111]
valueOf(Object obj) Conversion Returns string representation of object (static) String String.valueOf(123) → "123"
format(String format, Object... args) Conversion Returns formatted string (static) String String.format("Hello %s", "World") → "Hello World"
matches(String regex) Checking Tells if string matches given regex boolean "123".matches("\\d+") → true
repeat(int count) Modification Returns string repeated count times String "Hi".repeat(3) → "HiHiHi"
lines() Conversion Returns stream of lines extracted from string Stream<String> "a\nb\nc".lines().count() → 3
indent(int n) Modification Adjusts indentation of each line String "Hello\nWorld".indent(2) → adds 2 spaces
transform(Function<? super String, ? extends R> f) Conversion Applies function to string (Java 12+) R "hello".transform(s -> s.toUpperCase()) → "HELLO"
Important Notes:
  • String methods return new String objects (strings are immutable)
  • Use equals() for content comparison, not == (which compares references)
  • trim() removes only spaces (U+0020), strip() removes all whitespace characters
  • isEmpty() checks for length 0, isBlank() checks for whitespace-only strings
  • Many methods have overloaded versions with different parameters

3. String Comparison Methods

Java provides multiple ways to compare strings. Understanding the differences is crucial for correct string handling.

StringComparison.java
public class StringComparison {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = new String("Hello");
        String s4 = "HELLO";
        String s5 = "World";
        String s6 = "hello";
        
        System.out.println("=== Using == operator (reference comparison) ===");
        System.out.println("s1 == s2: " + (s1 == s2));  // true (same string pool)
        System.out.println("s1 == s3: " + (s1 == s3));  // false (different objects)
        
        System.out.println("\n=== Using equals() (content comparison) ===");
        System.out.println("s1.equals(s2): " + s1.equals(s2));      // true
        System.out.println("s1.equals(s3): " + s1.equals(s3));      // true
        System.out.println("s1.equals(s4): " + s1.equals(s4));      // false (case sensitive)
        System.out.println("s1.equals(s5): " + s1.equals(s5));      // false
        
        System.out.println("\n=== Using equalsIgnoreCase() ===");
        System.out.println("s1.equalsIgnoreCase(s4): " + s1.equalsIgnoreCase(s4));  // true
        System.out.println("s1.equalsIgnoreCase(s6): " + s1.equalsIgnoreCase(s6));  // true
        
        System.out.println("\n=== Using compareTo() (lexicographical) ===");
        System.out.println("\"apple\".compareTo(\"banana\"): " + "apple".compareTo("banana"));  // negative
        System.out.println("\"banana\".compareTo(\"apple\"): " + "banana".compareTo("apple"));  // positive
        System.out.println("\"apple\".compareTo(\"apple\"): " + "apple".compareTo("apple"));    // zero
        System.out.println("\"Apple\".compareTo(\"apple\"): " + "Apple".compareTo("apple"));    // negative (A < a)
        
        System.out.println("\n=== Using compareToIgnoreCase() ===");
        System.out.println("\"Apple\".compareToIgnoreCase(\"apple\"): " + 
                          "Apple".compareToIgnoreCase("apple"));  // zero
        
        System.out.println("\n=== compareTo() return values ===");
        System.out.println("Return < 0: First string comes before second");
        System.out.println("Return = 0: Strings are equal");
        System.out.println("Return > 0: First string comes after second");
        
        System.out.println("\n=== Real-world example: Sorting ===");
        String[] fruits = {"Banana", "apple", "Cherry", "date", "Apricot"};
        
        System.out.println("Original array:");
        for(String fruit : fruits) System.out.print(fruit + " ");
        
        // Case-sensitive sort
        java.util.Arrays.sort(fruits);
        System.out.println("\n\nCase-sensitive sorted:");
        for(String fruit : fruits) System.out.print(fruit + " ");
        
        // Case-insensitive sort
        java.util.Arrays.sort(fruits, String.CASE_INSENSITIVE_ORDER);
        System.out.println("\n\nCase-insensitive sorted:");
        for(String fruit : fruits) System.out.print(fruit + " ");
        
        System.out.println("\n\n=== Best Practices ===");
        System.out.println("1. Use equals() for content comparison");
        System.out.println("2. Use equalsIgnoreCase() for case-insensitive comparison");
        System.out.println("3. Use compareTo() for sorting/ordering");
        System.out.println("4. Never use == for content comparison (except null checks)");
    }
}
Method Comparison Type Returns Case Sensitive Use Case
== operator Reference comparison boolean N/A Check if same object in memory
equals() Content comparison boolean Yes General content equality check
equalsIgnoreCase() Content comparison boolean No Case-insensitive equality check
compareTo() Lexicographical int Yes Sorting, ordering strings
compareToIgnoreCase() Lexicographical int No Case-insensitive sorting

4. String Manipulation Examples

Common String Operations
public class StringManipulation {
    public static void main(String[] args) {
        String text = "   Java Programming Language   ";
        
        System.out.println("Original: \"" + text + "\"");
        System.out.println("Length: " + text.length());
        System.out.println("Trimmed: \"" + text.trim() + "\"");
        System.out.println("Uppercase: \"" + text.toUpperCase() + "\"");
        System.out.println("Lowercase: \"" + text.toLowerCase() + "\"");
        
        System.out.println("\n=== Substring Operations ===");
        String sentence = "The quick brown fox jumps over the lazy dog";
        System.out.println("Original: " + sentence);
        System.out.println("Substring(4, 9): " + sentence.substring(4, 9));  // quick
        System.out.println("Substring(10): " + sentence.substring(10));      // brown fox...
        
        System.out.println("\n=== Search Operations ===");
        System.out.println("Index of 'fox': " + sentence.indexOf("fox"));      // 16
        System.out.println("Last index of 'the': " + sentence.lastIndexOf("the"));  // 31
        System.out.println("Contains 'brown': " + sentence.contains("brown"));      // true
        System.out.println("Starts with 'The': " + sentence.startsWith("The"));     // true
        System.out.println("Ends with 'dog': " + sentence.endsWith("dog"));         // true
        
        System.out.println("\n=== Replace Operations ===");
        String original = "I love Java. Java is awesome!";
        System.out.println("Original: " + original);
        System.out.println("Replace 'Java' with 'Python': " + 
                          original.replace("Java", "Python"));
        System.out.println("Replace all spaces: " + 
                          original.replaceAll(" ", "-"));
        System.out.println("Replace first 'Java': " + 
                          original.replaceFirst("Java", "Python"));
        
        System.out.println("\n=== Split and Join ===");
        String csv = "John,Doe,30,New York";
        String[] parts = csv.split(",");
        System.out.println("Split by comma:");
        for(int i = 0; i < parts.length; i++) {
            System.out.println("  Part " + i + ": " + parts[i]);
        }
        
        String joined = String.join(" - ", parts);
        System.out.println("Joined with ' - ': " + joined);
        
        System.out.println("\n=== Character Operations ===");
        String word = "Hello";
        System.out.println("Word: " + word);
        System.out.println("First char: " + word.charAt(0));
        System.out.println("Last char: " + word.charAt(word.length() - 1));
        
        System.out.println("\nCharacters in reverse:");
        for(int i = word.length() - 1; i >= 0; i--) {
            System.out.print(word.charAt(i));
        }
        
        System.out.println("\n\n=== Pattern Matching ===");
        String email = "user@example.com";
        String phone = "123-456-7890";
        String date = "2023-12-25";
        
        System.out.println("Email '" + email + "' matches pattern: " + 
                          email.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"));
        System.out.println("Phone '" + phone + "' matches pattern: " + 
                          phone.matches("\\d{3}-\\d{3}-\\d{4}"));
        System.out.println("Date '" + date + "' matches pattern: " + 
                          date.matches("\\d{4}-\\d{2}-\\d{2}"));
        
        System.out.println("\n=== Modern Java Methods (Java 11+) ===");
        String spaced = "  Hello World  ";
        System.out.println("Original: \"" + spaced + "\"");
        System.out.println("strip(): \"" + spaced.strip() + "\"");
        System.out.println("stripLeading(): \"" + spaced.stripLeading() + "\"");
        System.out.println("stripTrailing(): \"" + spaced.stripTrailing() + "\"");
        System.out.println("isBlank(): " + spaced.isBlank());
        System.out.println("isEmpty(): " + spaced.isEmpty());
        System.out.println("\"Hi\".repeat(3): " + "Hi".repeat(3));
        
        String multiline = "Line1\nLine2\nLine3";
        System.out.println("\nMultiline string lines count: " + 
                          multiline.lines().count());
    }
}

5. StringBuilder & StringBuffer

For mutable string operations, Java provides StringBuilder (non-synchronized, faster) and StringBuffer (synchronized, thread-safe) classes.

StringBuilderExample.java
public class StringBuilderExample {
    public static void main(String[] args) {
        System.out.println("=== StringBuilder (Mutable, Not Thread-Safe) ===");
        StringBuilder sb = new StringBuilder("Hello");
        
        // Append operations
        sb.append(" ");
        sb.append("World");
        sb.append("!");
        System.out.println("After append: " + sb);  // Hello World!
        
        // Insert
        sb.insert(6, "Beautiful ");
        System.out.println("After insert: " + sb);  // Hello Beautiful World!
        
        // Replace
        sb.replace(0, 5, "Hi");
        System.out.println("After replace: " + sb);  // Hi Beautiful World!
        
        // Delete
        sb.delete(3, 13);
        System.out.println("After delete: " + sb);  // Hi World!
        
        // Reverse
        sb.reverse();
        System.out.println("After reverse: " + sb);  // !dlroW iH
        
        sb.reverse();  // Back to normal
        
        // Capacity methods
        System.out.println("\nStringBuilder Details:");
        System.out.println("Length: " + sb.length());           // 9
        System.out.println("Capacity: " + sb.capacity());       // 21 (default 16 + 5)
        sb.ensureCapacity(50);
        System.out.println("Capacity after ensure: " + sb.capacity());
        
        // Performance comparison
        System.out.println("\n=== Performance Test ===");
        int iterations = 100000;
        
        // Using String (creates new objects)
        long startTime = System.currentTimeMillis();
        String result = "";
        for(int i = 0; i < iterations; i++) {
            result += "a";  // Creates new string each time
        }
        long stringTime = System.currentTimeMillis() - startTime;
        
        // Using StringBuilder
        startTime = System.currentTimeMillis();
        StringBuilder sb2 = new StringBuilder();
        for(int i = 0; i < iterations; i++) {
            sb2.append("a");  // Modifies existing buffer
        }
        String sbResult = sb2.toString();
        long sbTime = System.currentTimeMillis() - startTime;
        
        System.out.println("String concatenation time: " + stringTime + "ms");
        System.out.println("StringBuilder time: " + sbTime + "ms");
        System.out.println("StringBuilder is " + (stringTime/sbTime) + "x faster!");
        
        System.out.println("\n=== StringBuffer (Thread-Safe) ===");
        StringBuffer sbf = new StringBuffer("Thread");
        sbf.append(" Safe");
        System.out.println("StringBuffer: " + sbf);
        
        System.out.println("\n=== Comparison Table ===");
        System.out.println("+----------------+----------------+----------------+----------------+");
        System.out.println("| Feature        | String         | StringBuilder  | StringBuffer   |");
        System.out.println("+----------------+----------------+----------------+----------------+");
        System.out.println("| Mutability     | Immutable      | Mutable        | Mutable        |");
        System.out.println("| Thread Safety  | Yes            | No             | Yes            |");
        System.out.println("| Performance    | Slow for concat| Fast           | Moderate       |");
        System.out.println("| Synchronized   | N/A            | No             | Yes            |");
        System.out.println("| Use Case       | Fixed strings  | Single thread  | Multi-thread   |");
        System.out.println("+----------------+----------------+----------------+----------------+");
        
        System.out.println("\n=== When to Use What ===");
        System.out.println("1. Use String for: Constants, fixed text, keys, configuration");
        System.out.println("2. Use StringBuilder for: Building strings in methods (single-threaded)");
        System.out.println("3. Use StringBuffer for: Building strings in multi-threaded environments");
    }
}
Method StringBuilder StringBuffer Description
append() Appends string representation of argument
insert() Inserts at specified position
delete() Deletes characters between indices
deleteCharAt() Deletes character at specified index
replace() Replaces characters between indices
reverse() Reverses the sequence
capacity() Returns current capacity
ensureCapacity() Ensures minimum capacity
setLength() Sets length of character sequence
setCharAt() Sets character at index

6. Practical String Examples

Example 1: User Input Validation

import java.util.Scanner;

public class UserValidation {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("=== User Registration Form ===");
        
        // Name validation
        String name;
        while(true) {
            System.out.print("Enter full name (2-50 chars): ");
            name = scanner.nextLine().trim();
            
            if(name.length() < 2 || name.length() > 50) {
                System.out.println("Name must be 2-50 characters!");
                continue;
            }
            
            if(!name.matches("^[a-zA-Z\\s]+$")) {
                System.out.println("Name can only contain letters and spaces!");
                continue;
            }
            
            break;
        }
        
        // Email validation
        String email;
        while(true) {
            System.out.print("Enter email: ");
            email = scanner.nextLine().trim().toLowerCase();
            
            if(!email.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
                System.out.println("Invalid email format! Use: user@example.com");
                continue;
            }
            
            break;
        }
        
        // Password validation
        String password;
        while(true) {
            System.out.print("Enter password (min 8 chars, with digit & special char): ");
            password = scanner.nextLine();
            
            if(password.length() < 8) {
                System.out.println("Password must be at least 8 characters!");
                continue;
            }
            
            if(!password.matches(".*\\d.*")) {
                System.out.println("Password must contain at least one digit!");
                continue;
            }
            
            if(!password.matches(".*[!@#$%^&*].*")) {
                System.out.println("Password must contain at least one special character!");
                continue;
            }
            
            // Confirm password
            System.out.print("Confirm password: ");
            String confirmPassword = scanner.nextLine();
            
            if(!password.equals(confirmPassword)) {
                System.out.println("Passwords don't match!");
                continue;
            }
            
            break;
        }
        
        // Phone validation
        String phone;
        while(true) {
            System.out.print("Enter phone (XXX-XXX-XXXX): ");
            phone = scanner.nextLine().trim();
            
            // Remove non-digits
            String digitsOnly = phone.replaceAll("[^\\d]", "");
            
            if(digitsOnly.length() != 10) {
                System.out.println("Phone must have 10 digits!");
                continue;
            }
            
            // Format phone
            phone = digitsOnly.replaceFirst("(\\d{3})(\\d{3})(\\d{4})", "$1-$2-$3");
            break;
        }
        
        // Display user information
        System.out.println("\n=== Registration Successful ===");
        System.out.println("Name: " + name);
        System.out.println("Email: " + email);
        System.out.println("Phone: " + phone);
        System.out.println("Password: " + "*".repeat(password.length()));
        
        // Generate username (first initial + last name)
        String[] nameParts = name.split(" ");
        String username = "";
        if(nameParts.length >= 2) {
            username = nameParts[0].charAt(0) + nameParts[nameParts.length - 1];
        } else {
            username = name.toLowerCase().replaceAll("\\s", "");
        }
        username = username.toLowerCase();
        System.out.println("Suggested username: " + username);
        
        scanner.close();
    }
}

Example 2: Text Processing Utility

public class TextProcessor {
    
    // Count words in text
    public static int countWords(String text) {
        if(text == null || text.isBlank()) {
            return 0;
        }
        String[] words = text.trim().split("\\s+");
        return words.length;
    }
    
    // Count characters (excluding spaces)
    public static int countCharacters(String text) {
        if(text == null) return 0;
        return text.replaceAll("\\s", "").length();
    }
    
    // Reverse string
    public static String reverse(String text) {
        if(text == null) return null;
        return new StringBuilder(text).reverse().toString();
    }
    
    // Check palindrome
    public static boolean isPalindrome(String text) {
        if(text == null) return false;
        String clean = text.toLowerCase().replaceAll("[^a-z0-9]", "");
        String reversed = new StringBuilder(clean).reverse().toString();
        return clean.equals(reversed);
    }
    
    // Count vowel occurrences
    public static int countVowels(String text) {
        if(text == null) return 0;
        String lower = text.toLowerCase();
        int count = 0;
        for(char c : lower.toCharArray()) {
            if("aeiou".indexOf(c) != -1) {
                count++;
            }
        }
        return count;
    }
    
    // Remove duplicate words
    public static String removeDuplicates(String text) {
        if(text == null || text.isBlank()) return text;
        String[] words = text.split("\\s+");
        StringBuilder result = new StringBuilder();
        java.util.LinkedHashSet uniqueWords = new java.util.LinkedHashSet<>();
        
        for(String word : words) {
            uniqueWords.add(word.toLowerCase());
        }
        
        for(String word : uniqueWords) {
            result.append(word).append(" ");
        }
        
        return result.toString().trim();
    }
    
    // Capitalize first letter of each word
    public static String capitalizeWords(String text) {
        if(text == null || text.isBlank()) return text;
        String[] words = text.split("\\s+");
        StringBuilder result = new StringBuilder();
        
        for(String word : words) {
            if(!word.isEmpty()) {
                result.append(Character.toUpperCase(word.charAt(0)))
                      .append(word.substring(1).toLowerCase())
                      .append(" ");
            }
        }
        
        return result.toString().trim();
    }
    
    // Extract email addresses from text
    public static java.util.List extractEmails(String text) {
        java.util.List emails = new java.util.ArrayList<>();
        if(text == null) return emails;
        
        java.util.regex.Pattern pattern = 
            java.util.regex.Pattern.compile("[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}");
        java.util.regex.Matcher matcher = pattern.matcher(text);
        
        while(matcher.find()) {
            emails.add(matcher.group());
        }
        
        return emails;
    }
    
    public static void main(String[] args) {
        String sampleText = "Hello world! Hello again. The quick brown fox jumps over the lazy dog. " +
                           "Contact me at john@example.com or support@company.org for more info.";
        
        System.out.println("=== Text Processing Demo ===\n");
        System.out.println("Original Text:");
        System.out.println(sampleText);
        System.out.println("\n" + "=".repeat(50) + "\n");
        
        System.out.println("Word Count: " + countWords(sampleText));
        System.out.println("Character Count (no spaces): " + countCharacters(sampleText));
        System.out.println("Vowel Count: " + countVowels(sampleText));
        
        System.out.println("\nReversed Text:");
        System.out.println(reverse(sampleText));
        
        System.out.println("\nCapitalized Text:");
        System.out.println(capitalizeWords(sampleText));
        
        System.out.println("\nWithout Duplicate Words:");
        System.out.println(removeDuplicates(sampleText));
        
        System.out.println("\nPalindrome Check:");
        System.out.println("\"racecar\" is palindrome: " + isPalindrome("racecar"));
        System.out.println("\"hello\" is palindrome: " + isPalindrome("hello"));
        System.out.println("\"A man, a plan, a canal: Panama\" is palindrome: " + 
                          isPalindrome("A man, a plan, a canal: Panama"));
        
        System.out.println("\nExtracted Emails:");
        java.util.List emails = extractEmails(sampleText);
        for(String email : emails) {
            System.out.println("  - " + email);
        }
        
        // Performance test
        System.out.println("\n" + "=".repeat(50));
        System.out.println("Performance Test: Building Large String");
        
        int iterations = 10000;
        long startTime, endTime;
        
        // Using String
        startTime = System.currentTimeMillis();
        String strResult = "";
        for(int i = 0; i < iterations; i++) {
            strResult += "word" + i + " ";
        }
        endTime = System.currentTimeMillis();
        System.out.println("String concatenation: " + (endTime - startTime) + "ms");
        
        // Using StringBuilder
        startTime = System.currentTimeMillis();
        StringBuilder sbResult = new StringBuilder();
        for(int i = 0; i < iterations; i++) {
            sbResult.append("word").append(i).append(" ");
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder: " + (endTime - startTime) + "ms");
    }
}

7. String Best Practices

Common String Mistakes:
  1. Using == instead of equals() for content comparison
  2. Concatenating strings in loops (creates many intermediate objects)
  3. Not checking for null before calling string methods
  4. Using substring() without checking bounds
  5. Forgetting that strings are immutable (modification returns new object)
  6. Using String when StringBuilder is more appropriate
Best Practices
  • Use StringBuilder for string concatenation in loops
  • Always use equals() for content comparison
  • Check for null before string operations
  • Use string literals when possible (better performance)
  • Prefer String.join() over manual concatenation
  • Use String.format() for complex formatting
  • Cache frequently used strings if performance critical
Performance Tips
  • StringBuilder is 100-200x faster than String concatenation in loops
  • String.intern() can save memory for duplicate strings
  • Avoid + operator in loops - use StringBuilder
  • Use char[] for character-level manipulation
  • Pre-compile regex patterns if used repeatedly
  • Use String.valueOf() instead of "" + obj

String Memory Optimization

String Pool: Reuses string literals
String.intern(): Manually add strings to pool
StringBuilder: Reduce object creation
char[] arrays: For intensive character manipulation