Java String Methods
Table of Contents + −
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()orreplace()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 charactersSystem.out.println(name.charAt(0)); // first characterSystem.out.println(name.charAt(3)); // fourth characterWalking through it:
length()returns4, 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, socharAt(4)throws an error.
Output
4Jalength() 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()); // HELLOSystem.out.println(word.toLowerCase()); // helloSystem.out.println(word); // still HelloThe 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
HELLOhelloHello🔍 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)andendsWith(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 foundSystem.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")returns14, where the first “Java” begins.lastIndexOf("Java")returns24, where the second “Java” begins.indexOf("Python")returns-1, because it is missing (not 0).contains,startsWith, andendsWitheach returntrueorfalse.
Use contains for a yes/no answer, and indexOf when you need the position.
Output
1424-1truetruetrue✂️ 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 fromstartto the end.substring(start, end)givesstartup to but not includingend.- The
endindex is exclusive, sosubstring(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 endSystem.out.println(text.substring(0, 5)); // index 0 up to (not including) 5Reading 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
WorldHello🧹 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 trimmedSystem.out.println("[" + messy.strip() + "]"); // same idea, newerBoth 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 commaSystem.out.println(text); // original unchangedreplace(",", " - ") 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 - threeone,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”, andparts.lengthis 3.- The argument is a pattern, so special characters like
.and|need"\\."or"\\|". Commas, spaces, and dashes pass as-is.
Output
First part: oneLast part: threeNumber 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 differsSystem.out.println(a.equalsIgnoreCase(b)); // true, case ignoredSystem.out.println(a.compareTo("Sam")); // negative, "Riya" comes firstSystem.out.println(a.compareTo("Riya")); // zero, they are equalReading the results:
equalsreturnsfalsebecause the first letter’s case differs.equalsIgnoreCasereturnstruebecause ignoring case they are the same.compareTo("Sam")returns a negative number; “Riya” comes before “Sam”.compareTo("Riya")returns0; they are equal.
For compareTo: negative means “I come first”, zero means “equal”, positive means “I come later” — exactly what sorting names needs.
Output
falsetrue-10➕ 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 concatSystem.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 CarterAlex 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 dotString 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..4Ignoring 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 spacess = 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 4System.out.println(s.charAt(3)); // ✅ last valid index is length() - 1, which is 3Using == 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 textif (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
equalsfor text, never==. And useequalsIgnoreCasewhen capital letters should not matter. - Pick the right search tool. Use
containsfor a yes or no, andindexOfwhen 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 andcharAt(i)reads one, both starting at index 0. - ✅
indexOf()andlastIndexOf()give a position or -1;contains(),startsWith(), andendsWith()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()orequalsIgnoreCase(), never==;compareTo()gives dictionary order. - ✅
split()breaks a String into an array, andconcat()or+joins Strings together.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does name.charAt(0) return?
Why: charAt(0) reads the character at index 0, which is the first one.
- 2
What does indexOf return when the text is not found?
Why: indexOf returns -1 to signal the text was not found.
- 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
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.