String Methods

B2.1.2 - Construct programs that can extract and manipulate substrings.


Key Concepts

String is not a primitive type - it is an object with built-in methods. Strings are immutable: no String method changes the original. Methods such as toUpperCase() and substring() return the result as a String, and you store it if you need it.

Quick Reference

Method What it returns Example
.length() Number of characters "Hi".length() → 2
.charAt(i) The char at index i "Hi".charAt(1) → 'i'
.substring(s) From index s to end "Hello".substring(2) → "llo"
.substring(s, e) From s up to (not incl.) e "Hello".substring(1, 4) → "ell"
.indexOf(str) Start index of str, or -1 "Hello".indexOf("ll") → 2
.toUpperCase() All uppercase "hi".toUpperCase() → "HI"
.toLowerCase() All lowercase "HI".toLowerCase() → "hi"
.equals(str) True if content matches "a".equals("a") → true
.equalsIgnoreCase(str) Matches ignoring case "A".equalsIgnoreCase("a") → true
.compareTo(str) Negative / 0 / positive "a".compareTo("b") → negative

(Python equivalents: len(s), s[i], s[a:b] slicing, s.find(...), s.upper(), s.lower(), and plain == / < / > for comparison.)

Common trap: substring(start, end) returns characters from start up to but not including end. "Hello".substring(1, 4) gives "ell" (indices 1, 2, 3) - index 4 is excluded.

Always compare Strings with .equals(), never ==. The == operator compares memory references, not content. (Python is the opposite: == compares content and IS the correct choice - there is no .equals().)


Worked Examples

Example 1: Basic String Methods

String name = "Hello, World!";

System.out.println(name.length());          // 13
System.out.println(name.charAt(0));         // 'H'
System.out.println(name.charAt(7));         // 'W'
System.out.println(name.substring(7));      // "World!"
System.out.println(name.substring(7, 12)); // "World"
System.out.println(name.indexOf("World")); // 7
System.out.println(name.indexOf("Java"));  // -1
System.out.println(name.toUpperCase());     // "HELLO, WORLD!"
System.out.println(name.toLowerCase());     // "hello, world!"
name = "Hello, World!"

# Python uses len(), indexing s[i], and slicing s[start:end] instead of methods
print(len(name))           # 13
print(name[0])             # "H"
print(name[7])             # "W"
print(name[7:])            # "World!"
print(name[7:12])          # "World"  - the end index is still excluded
print(name.find("World"))  # 7
print(name.find("Java"))   # -1
print(name.upper())        # "HELLO, WORLD!"
print(name.lower())        # "hello, world!"

Key points:

  • Indices start at 0, not 1
  • .length() uses parentheses (it’s a method call) - compare with array .length which has no parentheses
  • .indexOf() returns -1 if the substring is not found

Example 2: Parsing a Full Name

String fullName = "Alice Johnson";

int spaceIndex = fullName.indexOf(" ");                    // 5
String firstName = fullName.substring(0, spaceIndex);      // "Alice"
String lastName = fullName.substring(spaceIndex + 1);      // "Johnson"

System.out.println("First: " + firstName);
System.out.println("Last:  " + lastName);
System.out.println("Total characters: " + fullName.length());  // 13
full_name = "Alice Johnson"

space_index = full_name.find(" ")            # 5
first_name = full_name[0:space_index]        # "Alice"
last_name = full_name[space_index + 1:]      # "Johnson" - open-ended slice = "to the end"

print("First: " + first_name)
print("Last:  " + last_name)
print("Total characters: " + str(len(full_name)))   # 13

Pattern: Find a delimiter with indexOf(), then split with substring().


Example 3: Comparing Strings

String s1 = "apple";
String s2 = "apple";
String s3 = "APPLE";

System.out.println(s1.equals(s2));                // true
System.out.println(s1.equals(s3));                // false (case matters)
System.out.println(s1.equalsIgnoreCase(s3));      // true

System.out.println("apple".compareTo("banana"));  // negative (a < b)
System.out.println("cat".compareTo("cat"));        // 0 (equal)
System.out.println("dog".compareTo("cat"));        // positive (d > c)
s1 = "apple"
s2 = "apple"
s3 = "APPLE"

# Python compares string CONTENT with == - there is no .equals()
print(s1 == s2)                    # True
print(s1 == s3)                    # False (case matters)
print(s1.lower() == s3.lower())    # True - the equalsIgnoreCase pattern

# There is no compareTo() either - use < and > for alphabetical order
print("apple" < "banana")   # True ("apple" comes before)
print("cat" == "cat")       # True (equal)
print("dog" > "cat")        # True ("dog" comes after)

compareTo() returns:

  • Negative → first string comes before alphabetically
  • Zero → strings are equal
  • Positive → first string comes after alphabetically

Example 4: Building Strings Character by Character

String word = "Hello";
String reversed = "";

for (int i = word.length() - 1; i >= 0; i--) {
    reversed = reversed + word.charAt(i);
}

System.out.println(reversed);  // "olleH"
word = "Hello"
reversed_word = ""     # "reversed" is a built-in function name in Python, so we rename

for i in range(len(word) - 1, -1, -1):    # counts len-1 down to 0
    reversed_word = reversed_word + word[i]

print(reversed_word)   # "olleH"

Going through a string one character at a time (charAt(i) in Java, s[i] in Python) is the pattern behind counting, searching and reversing text.


Example 5: Counting Characters

String sentence = "The quick brown fox";
int spaceCount = 0;

for (int i = 0; i < sentence.length(); i++) {
    if (sentence.charAt(i) == ' ') {
        spaceCount++;
    }
}

System.out.println("Spaces: " + spaceCount);  // 3
sentence = "The quick brown fox"
space_count = 0

for i in range(len(sentence)):
    if sentence[i] == " ":      # no char type in Python - " " is a one-character string
        space_count = space_count + 1

print("Spaces:", space_count)   # 3

Notice == ' ' with single quotes - we are comparing char values (primitives), so == is correct here. Only use .equals() for String objects. (Python has no separate char type - == compares all strings, whatever their length.)


Quick Check

Q1. What does "Hello".substring(1, 4) return?

Q2. What does "Hello".indexOf("lo") return?

Q3. What does "Hello".indexOf("xyz") return?

Q4. After running this code, what is word?
String word = "hello"; word.toUpperCase();

Q5. Which is correct for getting the length of a String?


Trace Exercise

Trace this code - fill in the value of each variable.

String word = "Computer";
int len = word.length();
char first = word.charAt(0);
String sub = word.substring(3, 7);
String upper = word.toUpperCase();
word = "Computer"
length = len(word)     # "len" is the built-in function's name, so the variable is renamed
first = word[0]
sub = word[3:7]
upper = word.upper()

Hint: C=0, o=1, m=2, p=3, u=4, t=5, e=6, r=7

LineVariableValue
word.length() len
word.charAt(0) first
word.substring(3, 7) sub
word.toUpperCase() upper

Trace Exercise 2 - Parsing

Trace this code - work out the values step by step.

String email = "alice@school.edu";
int atIndex = email.indexOf("@");
String username = email.substring(0, atIndex);
String domain = email.substring(atIndex + 1);
int dotIndex = domain.indexOf(".");
String extension = domain.substring(dotIndex + 1);
email = "alice@school.edu"
at_index = email.find("@")
username = email[0:at_index]
domain = email[at_index + 1:]
dot_index = domain.find(".")
extension = domain[dot_index + 1:]
VariableValue
atIndex
username
domain
dotIndex
extension

Code Completion

This exercise practises the common pattern of splitting a string at a delimiter - use indexOf() to find the space, then substring() to extract the parts before and after it. Complete the code to extract the first name and last name from a full name.

String fullName = "John Smith";
int space = fullName.;
String first = fullName.;
String last = fullName.substring();
System.out.println("First: " + first);   // John
System.out.println("Last: " + last);     // Smith

Spot the Error

This code should check if two strings have the same content using an if statement, but it uses the wrong comparison operator. (With two literals in the same file, as here, this happens to print Match!, because Java reuses identical literals; with a word the user types it prints nothing, even when the word is hello. Either way == is the wrong test.) Find the bug.

String input = "hello";
String expected = "hello";
if (input == expected) {
    System.out.println("Match!");
}

What is wrong and how do you fix it?


This code should use charAt() to print the last character of a word, but it crashes with a StringIndexOutOfBoundsException. The bug tests your understanding of zero-based indexing. Find it.

String word = "Java";
char last = word.charAt(word.length());
System.out.println("Last char: " + last);

What is wrong and how do you fix it?


Predict the Output

This code demonstrates three core String methods - substring(), charAt(), and indexOf() - applied to the same string. Trace through each call carefully, remembering that indices start at 0 and substring(start, end) excludes the end index.

What does this code print?

String s = "Programming";
System.out.println(s.substring(0, 7));
System.out.println(s.charAt(3));
System.out.println(s.indexOf("gram"));
s = "Programming"
print(s[0:7])
print(s[3])
print(s.find("gram"))
Expected: Program
g
3

This code builds a new string by iterating through the characters of the original string in reverse order using charAt(). This is a classic string-reversal algorithm that combines loop traversal with string concatenation.

What does this code print?

String word = "Hello";
String result = "";
for (int i = word.length() - 1; i >= 0; i--) {
    result = result + word.charAt(i);
}
System.out.println(result);
word = "Hello"
result = ""
for i in range(len(word) - 1, -1, -1):
    result = result + word[i]
print(result)

Practice Exercises

Core

  1. Domain extractor - Read a URL like "www.google.com" and extract just "google".

  2. Replace first character - Read a word, replace the first letter with 'X' (use substring() to rebuild the string).

  3. File extension extractor - Read a file name from the user (e.g., "MyClass.java"). Extract and output the file extension. Strategy: indexOf(".") to find the dot, substring(dotIndex + 1) to extract the extension. Think about: what should happen if there is no dot?

Extension

  1. Word count - Count words in a sentence (count spaces + 1).

  2. Palindrome checker - Check if a word reads the same forwards and backwards using charAt().

  3. Initials method - Write a method public static String getInitials(String fullName) that returns the initials, for example "A.J." for "Alice Johnson".

Challenge

  1. Caesar cipher - Shift each character by N positions using charAt() and type casting.

  2. Title case - Convert "hello world from java" to "Hello World From Java".

Exam-Style (15 marks)

Student record parser - Given strings in the format "LastName, FirstName (ID)":

  • (a) Extract the last name [3 marks]
  • (b) Extract the first name [3 marks]
  • (c) Extract the ID (without parentheses) [3 marks]
  • (d) Write a method that takes a String[] of such records and returns a count of records with a given last name [6 marks]

GitHub Classroom

String Methods
Practice using length(), charAt(), substring(), indexOf(), and String comparison.

A class assignment on GitHub Classroom: use it when your teacher has set it. It needs a free GitHub account.

Working in the Codespace

  1. Accept and open. Accept the assignment above, open the link in the email from GitHub, then press Open in Codespace. In Java, change the status bar from Lightweight to Standard mode.
  2. Write and check. Open src/StringBasics.java and complete each TODO. Press Run and compare the output with the comments, or run bash run-tests.sh in the Terminal.
  3. Submit. In Source Control, write a message, press Commit, then Sync Changes. Your teacher’s feedback arrives as a pull request called Feedback.

There are four exercise files in src/: start with StringBasics.java and work down the list in the README.

The full Codespace guide, with pictures


Connections

Prerequisites:

Related Topics:

  • Iteration - loops for traversing Strings character by character
  • 1D Arrays - similar index-based access pattern

Where this leads: