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

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

Share & Connect