Working with Strings in Java

Strings hold text. Names, messages, file paths, user input, JSON data. Almost every program works with strings constantly. Java provides powerful tools for creating, examining, and manipulating them.

Creating Strings

The simplest way to create a String is with double quotes:

String greeting = "Hello, World!";
String name = "Alice";
String empty = "";

You can also use the new keyword, though it’s rarely necessary:

String greeting = new String("Hello, World!");

Both approaches create a String object. The literal syntax (double quotes) is preferred because it’s shorter and allows Java to optimize memory usage through string pooling.

Strings Are Immutable

Once created, a String cannot be changed. This surprises many beginners.

String name = "Alice";
name.toUpperCase();
System.out.println(name);  // Still "Alice"

The toUpperCase() method doesn’t modify the original String. It returns a new String with the changes. To keep the result, assign it:

String name = "Alice";
name = name.toUpperCase();
System.out.println(name);  // "ALICE"

Every String method that appears to modify a String actually returns a new one. The original stays unchanged. This immutability makes Strings safe to share across different parts of your program without unexpected side effects.

String Length

The length() method returns the number of characters:

String text = "Hello";
int len = text.length();  // 5

String empty = "";
int emptyLen = empty.length();  // 0

Spaces count as characters:

String spaced = "Hello World";
System.out.println(spaced.length());  // 11

Accessing Characters

Use charAt() to get a character at a specific position. Positions start at 0, not 1.

String text = "Hello";

char first = text.charAt(0);   // 'H'
char second = text.charAt(1);  // 'e'
char last = text.charAt(4);    // 'o'

Requesting a position outside the String throws an exception:

String text = "Hello";
char bad = text.charAt(10);  // StringIndexOutOfBoundsException

To safely get the last character:

String text = "Hello";
char last = text.charAt(text.length() - 1);  // 'o'

Concatenation

Join strings together with the + operator:

String first = "Hello";
String second = "World";
String combined = first + " " + second;  // "Hello World"

You can concatenate strings with other types. Java converts them automatically:

String name = "Alice";
int age = 30;
String message = name + " is " + age + " years old.";
// "Alice is 30 years old."

For building strings through many operations, use StringBuilder instead. Concatenation in loops creates many temporary String objects, which wastes memory.

// Inefficient for many iterations
String result = "";
for (int i = 0; i < 1000; i++) {
    result = result + i + " ";
}

// Better approach
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i).append(" ");
}
String result = sb.toString();

Comparing Strings

Use .equals() to compare String content. Don’t use ==.

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

System.out.println(a.equals(b));  // true
System.out.println(a.equals(c));  // true
System.out.println(a == c);       // false (different objects)

The == operator checks if two variables reference the same object in memory. Two Strings can have identical content but be stored as separate objects. Always use .equals() for content comparison.

For case-insensitive comparison, use equalsIgnoreCase():

String a = "Hello";
String b = "HELLO";

System.out.println(a.equals(b));            // false
System.out.println(a.equalsIgnoreCase(b));  // true

Searching Within Strings

Several methods help you find content inside a String.

contains() checks if a substring exists:

String sentence = "The quick brown fox";

boolean hasQuick = sentence.contains("quick");  // true
boolean hasSlow = sentence.contains("slow");    // false

startsWith() and endsWith() check the beginning and end:

String filename = "report.pdf";

boolean isPdf = filename.endsWith(".pdf");    // true
boolean isReport = filename.startsWith("report");  // true

indexOf() returns the position of a substring, or -1 if not found:

String text = "Hello World";

int pos = text.indexOf("World");  // 6
int missing = text.indexOf("xyz");  // -1

lastIndexOf() finds the last occurrence:

String path = "/home/user/documents/file.txt";
int lastSlash = path.lastIndexOf("/");  // 20

Extracting Substrings

The substring() method extracts part of a String.

With one argument, it extracts from that position to the end:

String text = "Hello World";
String world = text.substring(6);  // "World"

With two arguments, it extracts from the start position up to (but not including) the end position:

String text = "Hello World";
String hello = text.substring(0, 5);  // "Hello"

A common pattern extracts file extensions:

String filename = "document.pdf";
int dotPos = filename.lastIndexOf(".");
String extension = filename.substring(dotPos + 1);  // "pdf"

Changing Case

toUpperCase() and toLowerCase() convert all letters:

String mixed = "Hello World";

String upper = mixed.toUpperCase();  // "HELLO WORLD"
String lower = mixed.toLowerCase();  // "hello world"

These methods are useful for case-insensitive processing:

String input = "YES";
if (input.toLowerCase().equals("yes")) {
    System.out.println("User agreed");
}

Trimming Whitespace

The trim() method removes leading and trailing whitespace:

String padded = "   Hello World   ";
String trimmed = padded.trim();  // "Hello World"

This is essential when processing user input. People often accidentally add spaces before or after their text.

Java 11 added strip(), which handles Unicode whitespace better than trim(). For most cases they’re interchangeable.

Replacing Content

The replace() method substitutes characters or substrings:

String text = "Hello World";

String replaced = text.replace("World", "Java");  // "Hello Java"
String noL = text.replace("l", "");  // "Heo Word"

It replaces all occurrences, not just the first:

String text = "banana";
String result = text.replace("a", "o");  // "bonono"

Splitting Strings

The split() method divides a String into an array based on a delimiter:

String data = "apple,banana,cherry";
String[] fruits = data.split(",");

// fruits[0] = "apple"
// fruits[1] = "banana"
// fruits[2] = "cherry"

Process CSV-style data or break sentences into words:

String sentence = "The quick brown fox";
String[] words = sentence.split(" ");

for (String word : words) {
    System.out.println(word);
}

Output:

The
quick
brown
fox

Joining Strings

The opposite of splitting. String.join() combines an array with a delimiter:

String[] words = {"apple", "banana", "cherry"};
String joined = String.join(", ", words);  // "apple, banana, cherry"

Checking for Empty or Blank

isEmpty() returns true if the String has zero characters:

String empty = "";
String notEmpty = "hello";

System.out.println(empty.isEmpty());     // true
System.out.println(notEmpty.isEmpty());  // false

isBlank() (Java 11+) returns true if the String is empty or contains only whitespace:

String spaces = "   ";
String empty = "";

System.out.println(spaces.isEmpty());   // false
System.out.println(spaces.isBlank());   // true
System.out.println(empty.isBlank());    // true

Formatting Strings

String.format() creates strings with placeholders:

String name = "Alice";
int score = 95;

String message = String.format("%s scored %d points", name, score);
// "Alice scored 95 points"

Common format specifiers:

  • %s – String
  • %d – Integer
  • %f – Floating point
  • %.2f – Floating point with 2 decimal places
  • %n – Newline (platform-independent)
double price = 19.99;
String formatted = String.format("Price: $%.2f", price);
// "Price: $19.99"

Practical Example

Here’s a program that processes user information:

public class UserProcessor {
    public static void main(String[] args) {
        String rawInput = "  john.doe@email.com  ";
        
        // Clean the input
        String email = rawInput.trim().toLowerCase();
        
        // Validate format
        boolean hasAt = email.contains("@");
        boolean hasDot = email.contains(".");
        
        if (hasAt && hasDot) {
            // Extract username
            int atPos = email.indexOf("@");
            String username = email.substring(0, atPos);
            
            // Extract domain
            String domain = email.substring(atPos + 1);
            
            System.out.println("Email: " + email);
            System.out.println("Username: " + username);
            System.out.println("Domain: " + domain);
        } else {
            System.out.println("Invalid email format");
        }
    }
}

Output:

Email: john.doe@email.com
Username: john.doe
Domain: email.com

Common Mistakes

Comparing Strings with ==. Always use .equals() for content comparison.

Forgetting Strings are immutable. Methods like toUpperCase() return new Strings. Assign the result.

Index out of bounds. String positions start at 0 and go to length() - 1. Check bounds before accessing characters.

Not trimming user input. Extra whitespace causes comparison failures and display issues. Always trim.

What’s Next

Strings let you work with text. Conditionals let your program make decisions based on that text and other values. The next tutorial covers if statements, else blocks, and switch expressions.


Related: Java Operators Explained | Java Conditionals: if, else, switch

Sources

  • Oracle. “Strings.” The Java Tutorials. docs.oracle.com
  • Oracle. “String (Java SE 21).” Java Documentation. docs.oracle.com
Scroll to Top