The messy sign-up list
The college fest sign-up sheet is a mess. People typed " Riya.Sharma@Gmail.COM ", "kabir@yahoo.co.in", "MEERA@gmail.com". Riya has to clean every email, find who used Gmail, and send each person a message starting with their name.
Sir, do I really have to loop through every character with charAt to find the @ and cut the email?
No, String already has methods for that. trim() and toLowerCase() clean it, indexOf('@') finds the position, substring cuts out the parts. One line each.
Do I need to remember all of them?
Remember them in families: inspect, search, extract, transform, build. And remember two traps: substring's end index is not included, and split treats its argument as a pattern, not plain text.
What are String methods?
String methods are instance methods of java.lang.String that inspect, search, extract or transform the characters of a String. Because String is immutable, every method that produces modified text returns a new String and leaves the original unchanged. Index-based methods use positions from 0 to length() - 1; search methods return -1 when nothing is found.
Ready-made tools for text: find something, cut a piece, clean it up, join pieces together. They never damage the original; they hand you a new result.
Words you'll meet in this lesson
substring(begin, end), begin is included, end is excluded.split and replaceAll use it.s.trim().toLowerCase(): each call works on the previous result.Rules that apply to every method
| Original | Never changed. Store the result: s = s.trim(); |
|---|---|
| Not found | indexOf and lastIndexOf return -1 |
| Ranges | substring(2, 5) → indexes 2, 3, 4 (length 5 − 2 = 3) |
| Bad index | StringIndexOutOfBoundsException at run time |
| Called on null | NullPointerException: check for null first |
| Regex methods | split, replaceAll, matches: ., |, * and others have special meanings |
Exam tip: "Phatshala".substring(2, 5) is "ats": indexes 2, 3, 4. The length of a substring is always end - begin. Many MCQs test whether you include the end index.
The methods, by family
| Family | Methods | Example → result |
|---|---|---|
| Inspect | length(), charAt(i), isEmpty(), isBlank() | " ".isBlank() → true; " ".isEmpty() → false |
| Search | indexOf, lastIndexOf, contains, startsWith, endsWith | "banana".indexOf("an", 2) → 3 |
| Extract | substring, split, toCharArray | "a,b,,c".split(",") → [a, b, , c] |
| Transform | trim, strip, toUpperCase, toLowerCase, replace, replaceAll, repeat | "ab".repeat(3) → "ababab" |
| Compare | equals, equalsIgnoreCase, compareTo (Lesson 4.4) | "java".equalsIgnoreCase("JAVA") → true |
| Build / convert | String.join, String.format, String.valueOf, Integer.parseInt | String.format("%05d", 42) → "00042" |
The most-used methods, verified
public class Main {
public static void main(String[] args) {
String t = " MyPhatshala Java Course ".trim();
System.out.println("[" + t + "] length " + t.length());
System.out.println(t.indexOf("Java") + " " + t.indexOf('a') + " " + t.lastIndexOf('a') + " " + t.indexOf("Python"));
System.out.println(t.substring(12) + " | " + t.substring(0, 11) + " | " + t.substring(12, 16));
System.out.println(t.contains("Java") + " " + t.startsWith("My") + " " + t.endsWith("Course"));
System.out.println(t.replace("Java", "SQL"));
System.out.println(String.join(" | ", "Pune", "Delhi", "Agra"));
}
}replace vs replaceAll, trim vs strip, isEmpty vs isBlank
replace / replaceAll
replace works on plain text (all occurrences). replaceAll takes a regex: replaceAll("[0-9]", "#") hides every digit.
trim / strip
Both remove spaces at the ends. strip() (Java 11) also understands Unicode spaces; prefer it in new code.
isEmpty / isBlank
isEmpty(): length is 0. isBlank() (Java 11): empty or only spaces. Use isBlank for form fields.
The split trap: split takes a regular expression. "a.b.c".split(".") returns an empty array, because . means “any character”. Write split("\\."). The same applies to |, *, + and ?. Also, trailing empty pieces are dropped: "a,b,,".split(",") has only 2 elements.
Cleaning and cutting an email
Clean
String email = raw.trim().toLowerCase();trim()returns a new String without outer spaces;toLowerCase()is called on that result and returns another new String. Two objects created, the original untouched.Find
int at = email.indexOf('@');indexOfscans from index 0 until it finds the character, returning its position, or -1 if it reaches the end.Cut
String user = email.substring(0, at); String domain = email.substring(at + 1);substring(0, at)stops before the @.substring(at + 1)starts just after it and runs to the end. Each creates a new String with copied characters.Check
Compare content withboolean gmail = domain.equals("gmail.com");equals(Lesson 4.4). Since we lower-cased earlier, "Gmail.COM" also matches.Build the message
String msg = String.format("Hi %s, see you at the fest!", user);String.formatputs values into a pattern:%sfor text,%dfor whole numbers,%.2ffor 2 decimals.
Indexes, indexOf and substring: both views
Left: each method call and its result. Right: the characters with their index numbers.
"riya@mail.com" 6 steps- trim(): removes the spaces at both ends. 13 characters remain.
- toLowerCase(): R and M become small letters. Stored back in
s. - indexOf('@'): returns 4. For a character that isn't there, it returns -1.
- substring(0, 4): takes indexes 0, 1, 2, 3 → "riya". Length = 4 − 0 = 4.
- substring(5): one argument means “to the end”: "mail.com".
- split("@"): cuts at every @ and returns a
String[]of the pieces (Lesson 4.1).
trim()found the first and last non-space characters and copied the part between them into a new String.toLowerCase()creates another String; only indexes 0 and 5 actually changed letters.indexOfchecks index 0, 1, 2, 3, then finds '@' at 4 and stops. It returns the first match only;lastIndexOfsearches from the end.- The end index is a “stop before” marker. That's why
substring(0, at)neatly excludes the @. substring(begin)is short forsubstring(begin, length()).splitfinds each match of the pattern and collects the text between matches into a new array.
String methods in real systems
Most input arrives as text that must be cleaned, checked and taken apart; most output is text that must be built.
Watch it with an example: reading one line of a bank statement
Banks export statements as CSV text. Watch split, substring, contains and trim turn one line into useful data.
- Raw text: one line from a downloaded statement. Date, description and amount, separated by commas, with messy spaces.
- split(","): cuts the String at every comma and returns a
String[]with 3 parts. - substring(6): characters from index 6 to the end of "26-01-2025" give the year "2025".
- contains("UPI"): true, so this was a UPI payment. Expense apps tag transactions like this.
- trim() then parse: remove the spaces around " -450.00 ", then convert the text to the number −450.0.
- Done: one line became clean data. Note that every method returned a new value; the original line String never changed.
1. Importing files
CSV exports from banks, shops and spreadsheets are read line by line and split into fields; numbers are converted with parseInt and parseDouble.
2. Form validation and cleaning
Sign-up forms trim inputs, lower-case emails, check isBlank(), confirm a phone number has 10 digits and that a PAN or IFSC code has the right pattern.
3. Templates and messages
Emails, SMS and invoices fill placeholders with replace or String.format, and pad numbers into fixed formats like INV-2026-00042.
4. Search and URLs
Simple search boxes use toLowerCase().contains(…); blog and product pages turn titles into URL slugs with replaceAll; apps read query parameters by splitting on & and =.
Examples are simplified. Production code uses libraries for complex formats (CSV, JSON, URLs) because of edge cases like quoted commas and encoded characters.
The email cleaner
public class Main {
public static void main(String[] args) {
String raw = " Riya.Sharma@Gmail.COM ";
String email = raw.trim().toLowerCase();
int at = email.indexOf('@');
String user = email.substring(0, at);
String domain = email.substring(at + 1);
System.out.println("Clean: " + email);
System.out.println("User: " + user);
System.out.println("Domain: " + domain);
System.out.println("Gmail? " + domain.equals("gmail.com"));
boolean valid = at > 0 && email.indexOf('@', at + 1) == -1 && domain.contains(".");
System.out.println("Valid? " + valid);
}
}raw.trim().toLowerCase()Chained calls; the result is stored in a new variable.email.substring(0, at)Everything before the @ (end excluded).email.indexOf('@', at + 1) == -1Searching again after the first @ checks that there is only one.at > 0The @ isn't the first character (and was found at all).
Counting with indexOf(ch, from)
Each search starts just after the previous match, until indexOf returns -1.
Worked examples: real problems, solved and traced in memory
Three everyday text-processing jobs solved with String methods. Run each solution, then step through it to see every method call and every new String or array it creates.
Which email provider does each customer use?
Problem statement
The marketing team wants to know the email provider (the domain) of each sign-up. Emails arrive with stray spaces and capitals. Write domainOf(email) that returns the domain in lower case.
emails = {" Riya@Gmail.com", "kabir@YAHOO.co.in "}gmail.com yahoo.co.in
Approach
- Clean first:
trim()thentoLowerCase(), chained. - Find the position of
@withindexOf. substring(at + 1)takes everything after it.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Read one order line from a CSV file
Problem statement
Orders arrive as CSV lines: id,customer,quantity,price. Split the line, convert the numbers, and print the order total.
line = "ORD7,Meera,3,249.50"
ORD7 for Meera: Rs 748.50
Approach
split(",")returns a newString[]with one element per field.- Numbers are still text, so convert with
Integer.parseIntandDouble.parseDouble. - Multiply and format the total to 2 decimals.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Fill an SMS template
Problem statement
The delivery SMS template is Hi {name}, order {id} arrives {day}. Replace the placeholders with real values using chained replace calls.
name = "Kabir", id = "ORD-1042", day = "today"
Hi Kabir, order ORD-1042 arrives today.
Hi {name}, order {id} arrives {day}.Approach
replacereturns a new String with every occurrence replaced (plain text, no regex).- Chain the calls: each one works on the result of the previous one.
- Store the final result; the template itself stays reusable because it never changes.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Check yourself
Quick revision
Lesson 4.5 in one screen
- Families: inspect, search, extract, transform, compare, build.
- All return new Strings:
s = s.trim(); indexOf/lastIndexOf→ position or -1;indexOf(x, from)continues a search.substring(begin, end): end excluded, length = end − begin;substring(begin)to the end.splitandreplaceAlltake regex: escape.as"\\.";"\\s+"for any spaces.isBlank()for form fields;strip()in new code.String.join,repeat,String.format(%s %d %.2f %-10s %05d) build text.
Interview and viva questions
What's the difference between replace() and replaceAll()?
Both replace every occurrence. replace treats its arguments as plain text (char or CharSequence). replaceAll treats the first argument as a regular expression, so special characters like . or $ have meaning and need escaping.
Why is substring's end index exclusive?
It makes the maths simple: the length is end - begin, and adjacent ranges join without overlap, e.g. s.substring(0, i) + s.substring(i) is always the original string.
What's the difference between trim() and strip()?
trim() removes characters with codes up to 32 (space and control characters). strip(), added in Java 11, removes all Unicode whitespace, including special spaces that come from copy-pasted web text.
How do you split a string on a dot or a pipe?
Escape it, because split takes a regex: split("\\."), split("\\|"), or use split(Pattern.quote(".")).
How do you convert between Strings and numbers?
Text to number: Integer.parseInt("42"), Double.parseDouble("3.5") (throws NumberFormatException for bad text). Number to text: String.valueOf(42), Integer.toString(42) or "" + 42.
Practice problems
Now the built-in methods do the heavy lifting. For each problem, first decide which methods you need (indexOf? substring? split?), then write the code. The last four are real business tasks.
Get the domain from an email
Print the part of an email address after the @.
email = "riya.sharma@myphatshala.in"
User: riya.sharma Domain: myphatshala.in
Show solution and explanation
public class Main {
public static void main(String[] args) {
String email = "riya.sharma@myphatshala.in";
int at = email.indexOf('@');
String user = email.substring(0, at);
String domain = email.substring(at + 1);
System.out.println("User: " + user);
System.out.println("Domain: " + domain);
}
}How it works: indexOf('@') finds the position (11). substring(0, at) takes everything before it (end index excluded) and substring(at + 1) everything after it.
Count the words
Count the words in a sentence that may have extra spaces at the ends and between words.
text = " Java is fun to learn "
Words: 5
Show solution and explanation
public class Main {
public static void main(String[] args) {
String text = " Java is fun to learn ";
String t = text.trim();
int words = t.isEmpty() ? 0 : t.split("\\s+").length;
System.out.println("Words: " + words);
}
}How it works: trim() removes the outer spaces; split("\\s+") splits on one or more whitespace characters. Splitting on a single " " would create empty pieces for the double spaces. The empty check handles a blank sentence.
Allowed file types
An upload form accepts only PDF, JPG and PNG files, in any letter case. Check some file names.
"Resume.PDF", "photo.jpg", "virus.exe", "notes.pdf.exe"
Resume.PDF -> accepted photo.jpg -> accepted virus.exe -> rejected notes.pdf.exe -> rejected
Show solution and explanation
public class Main {
public static void main(String[] args) {
String[] files = {"Resume.PDF", "photo.jpg", "virus.exe", "notes.pdf.exe"};
for (String f : files) {
String name = f.toLowerCase();
boolean ok = name.endsWith(".pdf") || name.endsWith(".jpg") || name.endsWith(".png");
System.out.println(f + " -> " + (ok ? "accepted" : "rejected"));
}
}
}How it works: lower-case once, then check the ending. Using contains(".pdf") would wrongly accept “notes.pdf.exe”. (Real upload checks also inspect the file's content, not just its name.)
Fill in a message template
Replace placeholders in an SMS template with real values.
template = "Hi {name}, your order {id} will arrive on {date}."Hi Riya, your order ORD-1042 will arrive on 18 Oct.
Show solution and explanation
public class Main {
public static void main(String[] args) {
String template = "Hi {name}, your order {id} will arrive on {date}.";
String msg = template.replace("{name}", "Riya")
.replace("{id}", "ORD-1042")
.replace("{date}", "18 Oct");
System.out.println(msg);
}
}How it works: each replace returns a new String, so calls can be chained. replace changes every occurrence and treats the text literally (no regex), which makes it safe for placeholders.
Initials from a full name
Print the initials of a full name in capitals, with dots.
name = "riya kumari sharma"
R.K.S.
Show solution and explanation
public class Main {
public static void main(String[] args) {
String name = "riya kumari sharma";
String[] parts = name.trim().split("\\s+");
String initials = "";
for (String p : parts) {
initials += Character.toUpperCase(p.charAt(0)) + ".";
}
System.out.println(initials);
}
}How it works: split gives an array of words (Lesson 4.1). For each word, charAt(0) is its first letter. Character.toUpperCase works on a single char.
Count a word inside text
Count how many times “java” appears in a paragraph, ignoring case, including overlapping positions.
text = "Java is great. I use JAVA daily; javascript is different."
"java" found 3 times
Show solution and explanation
public class Main {
public static void main(String[] args) {
String text = "Java is great. I use JAVA daily; javascript is different.";
String hay = text.toLowerCase(), needle = "java";
int count = 0, from = 0;
while ((from = hay.indexOf(needle, from)) != -1) {
count++;
from++;
}
System.out.println("\"" + needle + "\" found " + count + " times");
}
}How it works: indexOf(needle, from) searches starting at from and returns −1 when nothing is left. Moving from forward by 1 after each hit continues the search. Note that “javascript” also contains “java”: plain text search doesn't know about whole words.
Reverse the word order
Reverse the order of words in a sentence (not the letters).
s = "learn Java the visual way"
way visual the Java learn
Show solution and explanation
public class Main {
public static void main(String[] args) {
String s = "learn Java the visual way";
String[] w = s.split(" ");
String result = "";
for (int i = w.length - 1; i >= 0; i--) {
result += w[i];
if (i > 0) result += " ";
}
System.out.println(result);
}
}How it works: split into an array, then walk it backwards. The if (i > 0) avoids a trailing space. With Java's collections you could also use Collections.reverse and String.join (Module 11).
Title case with substring
Convert a heading to Title Case: first letter of each word upper case, rest lower case.
h = "the JAVA string GUIDE"
The Java String Guide
Show solution and explanation
public class Main {
public static void main(String[] args) {
String h = "the JAVA string GUIDE";
String[] words = h.split(" ");
for (int i = 0; i < words.length; i++) {
String w = words[i];
words[i] = w.substring(0, 1).toUpperCase() + w.substring(1).toLowerCase();
}
System.out.println(String.join(" ", words));
}
}How it works: substring(0, 1) is the first letter as a String; substring(1) is the rest. Each word is replaced in the array, then String.join glues them back with spaces.
Is it a rotation?
Check whether one string is a rotation of another (e.g. “tionrota” is a rotation of “rotation”).
a = "rotation", b = "tionrota"
tionrota is a rotation of rotation
Show solution and explanation
public class Main {
public static void main(String[] args) {
String a = "rotation", b = "tionrota";
boolean rotation = a.length() == b.length() && (a + a).contains(b);
System.out.println(b + (rotation ? " is" : " is not") + " a rotation of " + a);
}
}How it works: doubling “rotation” gives “rotationrotation”, which contains every rotation of it. The length check stops shorter pieces like “tion” from counting. A classic interview trick.
Parse an order line from a CSV file
Each line of an orders file looks like ORD101,Riya Sharma,3,249.50 (id, customer, quantity, price). Print a readable summary with the total.
line = "ORD101,Riya Sharma,3,249.50"
Order ORD101 for Riya Sharma 3 x Rs 249.50 = Rs 748.50
Show solution and explanation
public class Main {
public static void main(String[] args) {
String line = "ORD101,Riya Sharma,3,249.50";
String[] f = line.split(",");
String id = f[0];
String customer = f[1].trim();
int qty = Integer.parseInt(f[2].trim());
double price = Double.parseDouble(f[3].trim());
System.out.println("Order " + id + " for " + customer);
System.out.println(qty + " x Rs " + String.format("%.2f", price) + " = Rs " + String.format("%.2f", qty * price));
}
}How it works: split(",") breaks the line into fields. Numbers arrive as text, so Integer.parseInt and Double.parseDouble convert them. Real CSV files can contain commas inside quotes, so production code uses a CSV library.
Mask an email for display
Show an email as r*********a@mail.com: keep the first and last letter of the user part, hide the rest.
"riya.sharma@mail.com", "ab@mail.com"
r*********a@mail.com a*@mail.com
Show solution and explanation
public class Main {
public static void main(String[] args) {
String[] emails = {"riya.sharma@mail.com", "ab@mail.com"};
for (String email : emails) {
int at = email.indexOf('@');
String user = email.substring(0, at);
String masked;
if (user.length() <= 2) {
masked = user.charAt(0) + "*";
} else {
masked = user.charAt(0) + "*".repeat(user.length() - 2) + user.charAt(user.length() - 1);
}
System.out.println(masked + email.substring(at));
}
}
}How it works: "*".repeat(n) (Java 11+) makes n stars. Very short user names are handled separately so nothing breaks. “Forgot password” pages show masked emails so a stranger can't learn someone's full address.
Make a URL slug
Blog URLs use a “slug”: lower case, words joined by hyphens, no symbols. Turn titles into slugs.
"Top 10 Java Tips for 2026!", " String vs StringBuilder: Which? "
top-10-java-tips-for-2026 string-vs-stringbuilder-which
Show solution and explanation
public class Main {
public static void main(String[] args) {
String[] titles = {"Top 10 Java Tips for 2026!", " String vs StringBuilder: Which? "};
for (String title : titles) {
String slug = title.trim().toLowerCase()
.replaceAll("[^a-z0-9 ]", "")
.replaceAll("\\s+", "-");
System.out.println(slug);
}
}
}How it works: replaceAll uses a regular expression. [^a-z0-9 ] means “any character that is not a letter, digit or space”, which we delete; then runs of spaces become one hyphen. Clean, readable URLs are also better for search engines.
Print an aligned receipt
Print a shop receipt with item names left-aligned and amounts right-aligned with 2 decimals.
items: Notebook 2 x 45.00, Gel pen 5 x 12.50, Geometry box 1 x 120.00
Item Qty Amount ---------------------------- Notebook 2 90.00 Gel pen 5 62.50 Geometry box 1 120.00 ---------------------------- TOTAL 272.50
Show solution and explanation
public class Main {
public static void main(String[] args) {
String[] items = {"Notebook", "Gel pen", "Geometry box"};
int[] qty = {2, 5, 1};
double[] price = {45.00, 12.50, 120.00};
double total = 0;
System.out.println(String.format("%-14s %3s %9s", "Item", "Qty", "Amount"));
System.out.println("-".repeat(28));
for (int i = 0; i < items.length; i++) {
double amount = qty[i] * price[i];
total += amount;
System.out.println(String.format("%-14s %3d %9.2f", items[i], qty[i], amount));
}
System.out.println("-".repeat(28));
System.out.println(String.format("%-18s %9.2f", "TOTAL", total));
}
}How it works: in String.format, %-14s pads text to 14 characters on the right (left-aligned), %3d right-aligns a number in 3 spaces, and %9.2f shows 2 decimals in 9 spaces. Fixed widths line the columns up.
Real-world scenario questions (asked in company interviews)
String methods are easy until real data arrives. Decide your answer first, then open the model answer.
The version check that always says “update required”
An app compares versions like "2.10.3" by doing String[] p = version.split("."); and reading p[0]. It crashes with ArrayIndexOutOfBoundsException. Why?
The interviewer is checking: do you know split takes a regular expression?
Show a strong answer
- In regex,
.means “any character”. Every character is a separator, all pieces are empty, and trailing empty pieces are removed, so the array has length 0. - Fix:
split("\\.")orsplit(Pattern.quote(".")). - Then compare the parts as numbers with
Integer.parseInt; comparing "10" and "9" as text says "10" is smaller.
Avoid: comparing whole version strings with compareTo: "2.10.3" sorts before "2.9.0" as text.
PIN code extraction crashes on short addresses
Code takes the last 6 characters of an address as the PIN: addr.substring(addr.length() - 6). It works for most rows but crashes for an address entered as "Pune", and returns garbage like "Road 5" for others. How do you make it robust?
The interviewer is checking: do you validate before cutting, and think about messy input?
Show a strong answer
- For "Pune",
length() - 6is negative →StringIndexOutOfBoundsException. Always check the length (or theindexOfresult) beforesubstring. - Position-based cutting assumes a fixed format. Instead, search for a 6-digit number, e.g. with a regex like
\\b\\d{6}\\b, or scan tokens fromsplit("\\s+")for one that's 6 digits. - Best: collect the PIN in its own form field and validate it there.
Avoid: catching the exception and returning an empty PIN silently. Flag bad records for review.
The CSV import that shifts columns
A bank-statement import uses line.split(","). Two problems appear: rows like 101,"Sharma, Riya",500 get 4 columns instead of 3, and rows ending with empty fields (102,Kabir,,) have fewer columns than expected. Explain both and what you'd do.
The interviewer is checking: do you know split's limits and when to use a proper parser?
Show a strong answer
- Split doesn't understand CSV quoting, so the comma inside
"Sharma, Riya"is treated as a separator. split(",")drops trailing empty strings;split(",", -1)keeps them so the column count stays correct.- For real files use a CSV library (for example Apache Commons CSV or OpenCSV), which handles quotes, escaped quotes and line breaks inside fields.
- Validate the column count of every row and report bad rows instead of guessing.
Avoid: writing your own quote-handling with more and more indexOf calls. It never covers every case.
Login works everywhere except Turkey
A permission check does if (role.toLowerCase().equals("admin")). Customers in Turkey report that admins named with the role "ADMIN" lose access. Nothing is wrong with their data. What could be happening?
The interviewer is checking: do you know that case conversion depends on the default locale?
Show a strong answer
toLowerCase()without arguments uses the JVM's default locale. In Turkish, upper-case I lowers to a dotless ı, so "ADMIN" becomes "admın", which doesn't equal "admin".- For identifiers, codes and keys, use
toLowerCase(Locale.ROOT), or simplyequalsIgnoreCase. - Keep locale-sensitive conversion only for text shown to users.
- Add a test that runs with a Turkish default locale.
Avoid: “It works on my machine.” Server and user locales differ.