Java String Methods

In the last lesson you learned about the Java String pool. Text gets useful once you can do things with it, like make it uppercase, find a word, or cut a piece out. Java gives the String a whole toolbox of built-in methods for exactly this.

What is a String method?

A method is an action you ask the String to perform. You write the String, a dot, the method name, and any extra info inside the brackets.

String result = someString.methodName(arguments);

One rule ties this whole lesson together: a String in Java is immutable. Once created, its text can never change.

  • Methods like toUpperCase() or replace() do not edit the String in place.
  • They return a new String. You must catch that returned value.
  • Ignore the return value and your text looks unchanged, and you wonder why.

Think of a photocopier: you feed in a page, ask for an uppercase copy, and out comes a fresh page. The original is untouched.

Length and reading single characters

Two basic questions: how long is it, and what character sits at a spot?

  • length() gives the character count.
  • charAt(index) reads one character.
  • Positions start at 0, not 1, just like arrays.

This example asks “Java” for its size and for two of its characters.

String name = "Java";
System.out.println(name.length()); // how many characters
System.out.println(name.charAt(0)); // first character
System.out.println(name.charAt(3)); // fourth character

Walking through it:

  • length() returns 4, because “Java” is four characters long.
  • charAt(0) reads index 0, the first character, 'J'.
  • charAt(3) reads index 3, the fourth character, 'a'.
  • The last valid index is length() - 1, so charAt(4) throws an error.

Output

4
J
a

length() with brackets for Strings

For a String it is name.length() with brackets, because it is a method. For an array it is array.length without brackets, because that is a field. People mix these two up all the time, so it is worth a second look whenever you write either one.

Changing the case

Turn text into all capitals or all small letters.

  • toUpperCase() returns an all-caps copy.
  • toLowerCase() returns an all-small copy.
  • Both return a new String; the original cannot change.

This example shows the case methods, and proves the original stays the same.

String word = "Hello";
System.out.println(word.toUpperCase()); // HELLO
System.out.println(word.toLowerCase()); // hello
System.out.println(word); // still Hello

The last line still prints “Hello”. The case methods handed back new Strings; word never changed. This is handy for comparing input: lowercase both “YES” and “yes” first and they match.

Output

HELLO
hello
Hello

Searching inside text

A few tools find things inside a String, each answering a different question.

  • indexOf(s) tells you where a piece of text first appears, as an index.
  • lastIndexOf(s) tells you where it appears last, scanning from the end.
  • contains(s) just tells you yes or no, is it in there at all.
  • startsWith(s) and endsWith(s) check the beginning and the ending.

This example searches a sentence in a few different ways.

String sentence = "I am learning Java, and Java is fun";
System.out.println(sentence.indexOf("Java")); // first position of "Java"
System.out.println(sentence.lastIndexOf("Java")); // last position of "Java"
System.out.println(sentence.indexOf("Python")); // not found
System.out.println(sentence.contains("learning")); // is it there?
System.out.println(sentence.startsWith("I am")); // does it start with this?
System.out.println(sentence.endsWith("fun")); // does it end with this?

Here is what each line gives back:

  • indexOf("Java") returns 14, where the first “Java” begins.
  • lastIndexOf("Java") returns 24, where the second “Java” begins.
  • indexOf("Python") returns -1, because it is missing (not 0).
  • contains, startsWith, and endsWith each return true or false.

Use contains for a yes/no answer, and indexOf when you need the position.

Output

14
24
-1
true
true
true

Cutting a piece out with substring

Take a slice out of a String with substring(). The second form is the most common String mistake, so go slow.

  • substring(start) gives everything from start to the end.
  • substring(start, end) gives start up to but not including end.
  • The end index is exclusive, so substring(0, 5) is indexes 0–4, five characters.

This example cuts the same String two ways.

String text = "Hello World";
System.out.println(text.substring(6)); // from index 6 to the end
System.out.println(text.substring(0, 5)); // index 0 up to (not including) 5

Reading the results:

  • substring(6) starts at index 6 and runs to the end, giving “World”.
  • substring(0, 5) takes indexes 0–4, giving “Hello”, leaving out index 5 (the space).
  • The length you get back is exactly end - start, which avoids off-by-one slips.

Output

World
Hello

Cleaning up spaces with trim and strip

Text from people is messy, with stray spaces at the start and end. Remove them with trim() or the newer strip().

  • trim() removes spaces from both ends, leaving inner spaces alone.
  • strip() does the same but understands more whitespace, like Unicode spaces (Java 11+).
  • For everyday text either is fine; for many languages, prefer strip().

This example cleans a value that has spaces on both sides.

String messy = " Alex ";
System.out.println("[" + messy.trim() + "]"); // ends trimmed
System.out.println("[" + messy.strip() + "]"); // same idea, newer

Both lines print [Alex]. The square brackets just show where the text begins and ends, so you can see the spaces are gone.

Output

[Alex]
[Alex]

Replacing text with replace

Swap one piece of text for another with replace().

  • It changes every match, not just the first.
  • It returns a new String, leaving the original alone.

This example turns commas into dashes.

String text = "one,two,three";
System.out.println(text.replace(",", " - ")); // swap every comma
System.out.println(text); // original unchanged

replace(",", " - ") changes each comma and returns a new String. The second line proves the original still has its commas; replace copied, it did not edit.

Output

one - two - three
one,two,three

Breaking text into parts with split

When a String holds several values joined by a separator, split() breaks it into an array of pieces. This is how you read comma-separated data or pull words from a sentence.

This example splits on the comma.

String text = "one,two,three";
String[] parts = text.split(","); // break on each comma
System.out.println("First part: " + parts[0]);
System.out.println("Last part: " + parts[2]);
System.out.println("Number of parts: " + parts.length);

What happens here:

  • split(",") cuts the text at each comma and returns an array of pieces.
  • parts[0] is “one”, parts[2] is “three”, and parts.length is 3.
  • The argument is a pattern, so special characters like . and | need "\\." or "\\|". Commas, spaces, and dashes pass as-is.

Output

First part: one
Last part: three
Number of parts: 3

Comparing Strings the right way

This one trips up almost everyone. To check if two Strings hold the same text, use equals(), not ==. The == operator checks if they are the same object in memory; equals() checks if the characters match.

  • equals(other) is true when both Strings hold exactly the same characters, caps included.
  • equalsIgnoreCase(other) is true when they match if you ignore capital letters.
  • compareTo(other) returns a number that tells you the dictionary order.

This example compares a few names.

String a = "Riya";
String b = "riya";
System.out.println(a.equals(b)); // false, case differs
System.out.println(a.equalsIgnoreCase(b)); // true, case ignored
System.out.println(a.compareTo("Sam")); // negative, "Riya" comes first
System.out.println(a.compareTo("Riya")); // zero, they are equal

Reading the results:

  • equals returns false because the first letter’s case differs.
  • equalsIgnoreCase returns true because ignoring case they are the same.
  • compareTo("Sam") returns a negative number; “Riya” comes before “Sam”.
  • compareTo("Riya") returns 0; they are equal.

For compareTo: negative means “I come first”, zero means “equal”, positive means “I come later” — exactly what sorting names needs.

Output

false
true
-1
0

Joining text with concat and the plus sign

Stick two Strings together two ways.

  • concat() joins, but only Strings.
  • + is far more common and can join non-text values too, like a number.
  • Both build a new String.

This example joins a first name and a last name.

String first = "Alex";
String last = "Carter";
System.out.println(first.concat(" ").concat(last)); // using concat
System.out.println(first + " " + last); // using +

Both lines print “Alex Carter”. Use + for small joins. For building text inside a long loop, neither is ideal, and you will meet a faster tool in the next lesson.

Output

Alex Carter
Alex Carter

A quick reference

All the methods in one place. Each returns a new value and never changes the original String.

Method What it does Example result
length() Number of characters "Java".length() is 4
charAt(i) The character at index i "Java".charAt(0) is 'J'
indexOf(s) / lastIndexOf(s) First or last position of s, or -1 if missing "aba".indexOf("a") is 0
substring(a) / substring(a, b) Piece from a to end, or a up to (not including) b "Hello".substring(0, 2) is "He"
toUpperCase() / toLowerCase() Change the case "hi".toUpperCase() is "HI"
trim() / strip() Remove spaces at the ends " x ".trim() is "x"
replace(x, y) Swap every x for y "a,b".replace(",", "-") is "a-b"
contains(s) true if s is inside the text "Java".contains("av") is true
startsWith(s) / endsWith(s) true if it begins or ends with s "file.txt".endsWith(".txt") is true
equals(s) / equalsIgnoreCase(s) true if the text matches (with or without case) "a".equalsIgnoreCase("A") is true
compareTo(s) Negative, zero, or positive for dictionary order "a".compareTo("b") is negative
split(s) Break into an array on s "a,b".split(",") is ["a", "b"]
concat(s) / + Join two Strings into one "a".concat("b") is "ab"

Two small real tasks

Methods stick once you use a few together on a real job.

First task: clean up typed input with extra spaces and random caps into a tidy lowercase value.

String raw = " Hello THERE ";
String clean = raw.trim().toLowerCase(); // trim, then lowercase the result
System.out.println("[" + clean + "]");

The methods chain: raw.trim() returns a cleaned String, then .toLowerCase() runs on that result. Each step works on the output before it, so it reads left to right.

Output

[hello there]

Second task: pull the file extension from a file name. It is whatever comes after the last dot, so lastIndexOf and substring work together.

String fileName = "report.final.pdf";
int dot = fileName.lastIndexOf("."); // position of the last dot
String ext = fileName.substring(dot + 1); // everything after that dot
System.out.println("Extension: " + ext);

Use lastIndexOf, not indexOf, because the name has two dots and the extension sits after the last one. substring(dot + 1) starts past the dot, giving a clean “pdf”.

Output

Extension: pdf

Common Mistakes

A few slip-ups catch nearly everyone.

Getting substring’s second number wrong. The end index is excluded, so people read one character too few or too many.

String s = "Hello";
System.out.println(s.substring(0, 5)); // ❌ "you might expect Hell"
System.out.println(s.substring(0, 5)); // ✅ actually "Hello", index 5 is excluded so 0..4

Ignoring the returned value. This is the immutability trap. The method runs, returns a new String, and you forget to keep it.

String s = " hi ";
s.trim(); // ❌ result thrown away, s still has the spaces
s = s.trim(); // ✅ keep the returned value, now s is "hi"

Reading an index that is out of range. The last valid index is length() - 1, so going past it throws an error.

String s = "Java";
System.out.println(s.charAt(4)); // ❌ StringIndexOutOfBoundsException, no index 4
System.out.println(s.charAt(3)); // ✅ last valid index is length() - 1, which is 3

Using == to compare text. It compares objects, not characters, so it can be false even when the words look the same.

String a = "hi", b = "h" + "i";
if (a == b) { } // ❌ unreliable, checks identity not text
if (a.equals(b)) { } // ✅ checks the actual characters

Best Practices

Habits that keep String code clean and bug-free.

  • Always catch the returned value. Strings never change in place, so assign the result, like s = s.trim();.
  • Use equals for text, never ==. And use equalsIgnoreCase when capital letters should not matter.
  • Pick the right search tool. Use contains for a yes or no, and indexOf when you actually need the position.
  • Trim input before you check it. Real input often carries stray spaces, so clean it first, then compare or store.
  • Lowercase both sides before comparing case-insensitively. Or just call equalsIgnoreCase, which does it for you.
  • Chain methods to read left to right. Something like raw.trim().toLowerCase() is clear, because each step works on the one before it.

What You’ve Learned

Nicely done. That is a full toolbox now. The key String methods:

  • ✅ length() counts characters and charAt(i) reads one, both starting at index 0.
  • ✅ indexOf() and lastIndexOf() give a position or -1; contains(), startsWith(), and endsWith() give true or false.
  • ✅ substring() cuts a piece, and the second index is excluded.
  • ✅ toUpperCase(), toLowerCase(), trim(), replace(), and friends all return a new String and leave the original alone.
  • ✅ Compare text with equals() or equalsIgnoreCase(), never ==; compareTo() gives dictionary order.
  • ✅ split() breaks a String into an array, and concat() or + joins Strings together.

Check Your Knowledge

4 questions Show quiz Hide quiz

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does name.charAt(0) return?

    Why: charAt(0) reads the character at index 0, which is the first one.

  2. 2

    What does indexOf return when the text is not found?

    Why: indexOf returns -1 to signal the text was not found.

  3. 3

    What does "Hello World".substring(0, 5) give?

    Why: substring(0, 5) takes indexes 0 to 4 (up to but not including 5), which is 'Hello'.

  4. 4

    Why must you assign the result of toUpperCase()?

    Why: String methods return a new String; the original never changes, so you must keep the returned value.

What’s Next?

Now that you can act on text, the next step is comparing it correctly. The difference between == and equals() matters more than people expect. Let’s dig in next.

Java String Comparison