Virtual assistance

Java Strings

Master the art of string manipulation in Java. Learn about the String class, StringBuilder, StringBuffer, and essential string operations.

Java Strings Tutorial

What is JDK?

What are Strings in Java?

In Java, a string is a sequence of characters that is used to represent text. Strings are objects of the String class, which is part of the java.lang package. Strings are one of the most commonly used data types in Java programming because they allow us to work with text data.

Strings in Java are immutable, which means once a String object is created, its value cannot be changed. This immutability has important implications for performance and memory usage. When you perform operations that appear to modify a string, Java actually creates a new String object.

Creating Strings

There are two main ways to create strings in Java:

1. String Literals

String literals are created using double quotes and are stored in the string pool for memory efficiency:

public class StringLiterals {
    public static void main(String[] args) {
        // String literal - stored in string pool
        String str1 = "Hello, World!";
        String str2 = "Hello, World!";

        // Both str1 and str2 refer to the same object in the string pool
        System.out.println(str1 == str2); // true
    }
}
2. Using the new Keyword

Strings can also be created using the new keyword, which creates objects in the heap memory:

public class StringObjects {
    public static void main(String[] args) {
        // String object - created in heap memory
        String str1 = new String("Hello, World!");
        String str2 = new String("Hello, World!");

        // str1 and str2 refer to different objects
        System.out.println(str1 == str2); // false
        System.out.println(str1.equals(str2)); // true
    }
}

String Methods

The String class provides numerous methods for string manipulation. Here are some of the most commonly used ones:

Length and Character Access

public class StringMethods {
    public static void main(String[] args) {
        String str = "Hello, World!";

        // Get string length
        System.out.println("Length: " + str.length()); // 13

        // Get character at specific index
        System.out.println("Character at index 0: " + str.charAt(0)); // H

        // Get substring
        System.out.println("Substring (0-5): " + str.substring(0, 5)); // Hello
        System.out.println("Substring (7): " + str.substring(7)); // World!
    }
}

String Comparison

public class StringComparison {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");

        // Using == operator (compares references)
        System.out.println("str1 == str2: " + (str1 == str2)); // true
        System.out.println("str1 == str3: " + (str1 == str3)); // false

        // Using equals() method (compares content)
        System.out.println("str1.equals(str2): " + str1.equals(str2)); // true
        System.out.println("str1.equals(str3): " + str1.equals(str3)); // true

        // Case-insensitive comparison
        System.out.println("equalsIgnoreCase: " + "Hello".equalsIgnoreCase("HELLO")); // true

        // Compare lexicographically
        System.out.println("compareTo: " + "Apple".compareTo("Banana")); // Negative value
    }
}

Searching and Replacing

public class StringSearchReplace {
    public static void main(String[] args) {
        String str = "Hello, World! Welcome to Java programming.";

        // Check if string contains substring
        System.out.println("Contains 'Java': " + str.contains("Java")); // true

        // Find index of substring
        System.out.println("Index of 'World': " + str.indexOf("World")); // 7
        System.out.println("Last index of 'o': " + str.lastIndexOf("o")); // 27

        // Replace characters/substrings
        System.out.println("Replace 'o' with '0': " + str.replace('o', '0')); // Hell0, W0rld!
        System.out.println("Replace 'Java' with 'Python': " + str.replace("Java", "Python"));
    }
}

Case Conversion and Trimming

public class StringCaseTrim {
    public static void main(String[] args) {
        String str = "  Hello, World!  ";

        // Convert to uppercase/lowercase
        System.out.println("Uppercase: " + str.toUpperCase());
        System.out.println("Lowercase: " + str.toLowerCase());

        // Trim whitespace
        System.out.println("Trimmed: '" + str.trim() + "'");

        // Check if string starts/ends with substring
        System.out.println("Starts with '  He': " + str.startsWith("  He"));
        System.out.println("Ends with 'd!  ': " + str.endsWith("d!  "));
    }
}

String Concatenation

There are several ways to concatenate strings in Java:

1. Using the + Operator

public class StringConcatenation {
    public static void main(String[] args) {
        String firstName = "John";
        String lastName = "Doe";
        int age = 25;

        // Using + operator
        String message = "Hello, my name is " + firstName + " " + lastName + " and I am " + age + " years old.";
        System.out.println(message);
    }
}

2. Using concat() Method

public class StringConcat {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = " World";

        String result = str1.concat(str2);
        System.out.println(result); // Hello World
    }
}

3. Using StringBuilder (Recommended for multiple concatenations)

public class StringBuilderConcat {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();

        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        sb.append("!");
        sb.append(" Welcome to Java.");

        String result = sb.toString();
        System.out.println(result);
    }
}

StringBuilder vs StringBuffer

For mutable string operations, Java provides two classes: StringBuilder and StringBuffer. Both are used for creating mutable strings, but they differ in thread safety.

StringBuilder (Not Thread-Safe, Faster)

public class StringBuilderExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");

        sb.append(" World");           // Append string
        sb.insert(5, ",");             // Insert at position
        sb.replace(6, 11, "Java");     // Replace substring
        sb.delete(5, 6);               // Delete character
        sb.reverse();                   // Reverse string

        System.out.println(sb.toString());
        System.out.println("Capacity: " + sb.capacity());
        System.out.println("Length: " + sb.length());
    }
}

StringBuffer (Thread-Safe, Slower)

public class StringBufferExample {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("Hello");

        sb.append(" World");
        sb.insert(5, ",");
        sb.replace(6, 11, "Java");

        System.out.println(sb.toString());
    }
}

When to Use Which?

  • StringBuilder: Use in single-threaded environments where performance is critical
  • StringBuffer: Use in multi-threaded environments where thread safety is required
  • String: Use for immutable strings and simple operations

String Pool and Memory Management

Java maintains a special memory area called the "String Pool" (or "String Constant Pool") to store string literals. This optimization helps save memory by reusing string objects.

public class StringPool {
    public static void main(String[] args) {
        // These literals are stored in the string pool
        String s1 = "Hello";
        String s2 = "Hello";

        // s1 and s2 refer to the same object in the pool
        System.out.println(s1 == s2); // true

        // Using new keyword creates object in heap
        String s3 = new String("Hello");
        System.out.println(s1 == s3); // false

        // intern() method adds string to pool if not present
        String s4 = s3.intern();
        System.out.println(s1 == s4); // true
    }
}

String Formatting

Java provides several ways to format strings:

1. String.format()

public class StringFormatting {
    public static void main(String[] args) {
        String name = "Alice";
        int age = 30;
        double salary = 50000.50;

        // Using String.format()
        String formatted = String.format("Name: %s, Age: %d, Salary: $%.2f", name, age, salary);
        System.out.println(formatted);

        // Using printf() (same as format)
        System.out.printf("Name: %s, Age: %d%n", name, age);
    }
}

2. Text Blocks (Java 13+)

public class TextBlocks {
    public static void main(String[] args) {
        String html = """
            
                
                    

Hello, World!

"""; System.out.println(html); } }

Common String Operations

Splitting Strings

public class StringSplit {
    public static void main(String[] args) {
        String csv = "John,Doe,30,Engineer";
        String[] parts = csv.split(",");

        for (String part : parts) {
            System.out.println(part);
        }

        // Split with limit
        String sentence = "The quick brown fox jumps over the lazy dog";
        String[] words = sentence.split(" ", 3); // Split into 3 parts
        for (String word : words) {
            System.out.println(word);
        }
    }
}

Joining Strings

public class StringJoin {
    public static void main(String[] args) {
        String[] words = {"Hello", "World", "from", "Java"};

        // Using String.join()
        String result = String.join(" ", words);
        System.out.println(result); // Hello World from Java

        // Using StringJoiner
        java.util.StringJoiner joiner = new java.util.StringJoiner(", ", "[", "]");
        for (String word : words) {
            joiner.add(word);
        }
        System.out.println(joiner.toString()); // [Hello, World, from, Java]
    }
}

Best Practices for String Handling

  • Use StringBuilder for concatenation in loops: Avoid using + operator in loops as it creates many temporary objects
  • Use equals() for content comparison: Never use == to compare string contents
  • Consider string interning: Use intern() judiciously for memory optimization
  • Use StringBuilder over StringBuffer: Unless thread safety is required
  • Prefer String.format() for complex formatting: It's more readable than concatenation
  • Use trim() for user input: Always trim whitespace from user input strings
  • Consider String.isEmpty() over length checks: More readable and efficient

Performance Considerations

  • String immutability: Remember that strings are immutable - each modification creates a new object
  • StringBuilder capacity: Set initial capacity when you know the approximate size
  • Avoid unnecessary operations: Check string length before operations when possible
  • Use appropriate methods: Some methods are more efficient than others for specific operations

Mastering string manipulation is essential for Java development. Strings are used everywhere in Java applications, from simple text processing to complex data parsing. The next tutorial will cover Java methods, which allow you to organize your code into reusable functions.