Chapter 3 · Data
Working with text
Step 1 of 22 · Concept
A String is a row of characters
In this lesson you take text apart, compare it and format it.
String word = "Browser"; puts an arrow in the box word. The text sits on the heap, one character after another.
Each character has a number, its index, counted from 0.
| call | gives |
|---|---|
word.length() | 7: how many characters |
word.charAt(0) | B: the character at index 0 |
word.charAt(6) | r: the last one, at length() - 1 |
Step 2 of 22 · Quiz
The last character
String s = "Java"; What is s.charAt(s.length() - 1)?
Step 3 of 22 · Concept
substring cuts, indexOf searches
call on "Browser" | gives |
|---|---|
substring(0, 3) | "Bro": from index 0 up to 3, without 3 |
substring(3) | "wser": from index 3 to the end |
indexOf("s") | 4: the index where "s" first appears |
indexOf("z") | -1: there is no "z" |
Step 4 of 22 · Quiz
Cut it
What is "Browser".substring(1, 4)?
Step 5 of 22 · Concept
New text in another case
| call | gives |
|---|---|
"Ada".toUpperCase() | "ADA" |
"Ada".toLowerCase() | "ada" |
" Ada ".trim() | "Ada": the spaces at both ends removed |
Each of these gives back a String, so you can call the next method on it. " Ada ".trim().toLowerCase() trims,
then lowers: "ada". Calls in a row like this are chained.
Step 6 of 22 · Demo
Seven calls on one word
The calls of this part, all on the word "Browser". Run it, and match each line of the output to its call.
Step 7 of 22 · Exercise
Your turn: user and domain
Complete user and domain. Each takes an email address. user returns the part before the @, and domain
the part after it, both trimmed and in lower case.
The program must print:
User: ada
Domain: example.org
User: grace
Domain: navy.mil
Clean the text first, with two chained calls. Then find the @: its index tells you where to cut.
email.trim().toLowerCase() cleans it. With at, the index of the @: the user is substring(0, at), and the
domain starts at at + 1.
String clean = email.trim().toLowerCase();
int at = clean.indexOf("@");
return clean.substring(0, at);
Step 8 of 22 · Concept
A String never changes
Scanner in = new Scanner(System.in);
String word = in.nextLine(); // the user types Browser
word = word.toUpperCase();
in.nextLine() reads one line the user types, here "Browser". A String is immutable: no method changes it.
word.toUpperCase() makes a new String, "BROWSER", and = stores its arrow in word.
"Browser" never changed, but no arrow points at it now. The garbage collector removes it.
Step 9 of 22 · Quiz
Did it change?
What does this print?
String name = "ada";
name.toUpperCase();
System.out.println(name);
Step 10 of 22 · Try it
Try it: keep the new text
Run it: it prints ada. Change line 4 so that name points at the upper-case text, then run it again.
Store what toUpperCase() returns in name: name = …;.
Step 11 of 22 · Concept
== compares arrows
String a = "yes";
String b = "YES".toLowerCase();
a and b hold the same letters in two different objects.
a == basks: do both arrows point at the same object? Here:false.a.equals(b)asks: are the characters the same? Here:true.
Step 12 of 22 · Quiz
Predict the output
Type exactly what this program prints.
String a = "yes";
String b = "YES".toLowerCase();
System.out.println(a == b);
System.out.println(a.equals(b));
Step 13 of 22 · Demo
See it run
Run it and compare with your answer.
Step 14 of 22 · Concept
A char is one character
charAt gives a char: one character in single quotes, such as 'A'. A char is a plain value, like an int,
so == is right for it.
Characters come in order, so c >= 'A' && c <= 'Z' asks: is c a capital? capitals++ adds 1, as i++ does.
String text = "Hi, Al";
int capitals = 0;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c >= 'A' && c <= 'Z') {
capitals++;
}
}
Step 15 of 22 · Quiz
Is it a digit?
char c = text.charAt(i); Which question is true exactly when c is a digit?
Step 16 of 22 · Concept
printf fills in the blanks
System.out.printf prints a format: text with placeholders. The values after it fill them, in order.
| placeholder | stands for | printf … prints |
|---|---|---|
%d | a whole number | ("%d cats", 3) → 3 cats |
%s | text | ("Hi %s", "Ada") → Hi Ada |
%.2f | a double, 2 digits after the point | ("%.2f", 4.5) → 4.50 |
%5d | a whole number, 5 columns wide | ("%5d", 42) → 3 spaces, 42 |
%-8s | text, 8 wide, the spaces after it | ("%-8s", "Ada") → Ada, 5 spaces |
%n | the end of the line | printf does not end it by itself |
A number after % is a width: spaces fill the value out to that many columns.
Step 17 of 22 · Demo
Counting capitals
The loop counts the capitals, and printf prints the result. Run it. The spaces count as characters too.
In the last two lines, | marks where each column ends.
Step 18 of 22 · Exercise
Your turn: count the digits
Complete countDigits: it returns how many characters of its text are digits. Then complete report: it prints
one line with printf. The program must print:
R2-D2: 2 digits in 5 characters
2026-10-16: 8 digits in 10 characters
hello: 0 digits in 5 characters
countDigits works like the capitals loop: visit every index, and count the characters that are digits.
A digit is c >= '0' && c <= '9'. In report, the format is "%s: %d digits in %d characters%n".
System.out.printf("%s: %d digits in %d characters%n",
text, countDigits(text), text.length());
Step 19 of 22 · Concept
StringBuilder grows one text
text += "ha" makes a whole new String each time, because the old one cannot change. In a long loop, that is
slow.
A StringBuilder is text that can change. append adds to the same object, and toString() gives you the
String at the end.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) {
sb.append("ha");
}
String laugh = sb.toString(); // "hahaha"
Step 20 of 22 · Check yourself
Check yourself: name cards
Write the three methods, each as its comment says. The program must print exactly:
true
false
GH
grace hopper (GH): 4 vowels in 12 characters (0.33)
alan turing (AT): 4 vowels in 11 characters (0.36)
card cleans the name first, counts the vowels with a loop, then builds its line with String.format. It can
call initials.
Step 21 of 22 · Challenge · optional
Challenge: read it backwards
Optional. It earns the lesson's third star.
Complete reversed: it returns its text backwards, built with a StringBuilder. test then checks whether a word
reads the same both ways. The program must print:
level: true
Java: false
Racecar: true
Visit the indexes from the last one down to 0. i-- takes 1 away from i, as i++ adds 1.
The loop is for (int i = text.length() - 1; i >= 0; i--). Inside it, sb.append(text.charAt(i));.
StringBuilder sb = new StringBuilder();
for (int i = text.length() - 1; i >= 0; i--) {
sb.append(text.charAt(i));
}
return sb.toString();
Step 22 of 22 · Recap
Recap
- A String is a row of characters at the indexes 0 to
length() - 1. - A String never changes: its methods return a new String. Store it to keep it.
- Compare text with
equals.==asks if two arrows point at one object. - A
charis one character in single quotes.printffills in%d,%s,%.2fand widths:%5d. - A
StringBuildergrows one text in place.
Next: lesson 10 keeps many values of any type in a row: arrays.
Review
5 questions from this lesson, in a new order each time. Answer from memory: 3 of 5 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
public class Parts {
public static void main(String[] args) {
String word = "Browser";
int last = word.length() - 1;
System.out.println("length: " + word.length());
System.out.print("first and last: " + word.charAt(0));
System.out.println(word.charAt(last));
System.out.print("from 0 to 3: ");
System.out.println(word.substring(0, 3));
System.out.println("from 3 on: " + word.substring(3));
System.out.println("index of s: " + word.indexOf("s"));
System.out.println("index of z: " + word.indexOf("z"));
System.out.print(word.toUpperCase() + " ");
System.out.println(word.toLowerCase());
System.out.println("[" + " Ada ".trim() + "]");
}
}
public class Email {
static String user(String email) {
// before the @, trimmed, in lower case
return "";
}
static String domain(String email) {
// after the @, trimmed, in lower case
return "";
}
public static void main(String[] args) {
String email = " [email protected] ";
String other = "[email protected]";
System.out.println("User: " + user(email));
System.out.println("Domain: " + domain(email));
System.out.println("User: " + user(other));
System.out.println("Domain: " + domain(other));
}
}
public class Upper {
public static void main(String[] args) {
String name = "ada";
name.toUpperCase();
System.out.println(name);
}
}
public class Same {
public static void main(String[] args) {
String a = "yes";
String b = "YES".toLowerCase();
System.out.println(a == b);
System.out.println(a.equals(b));
}
}
public class Capitals {
public static void main(String[] args) {
String text = "Java Runs In The Browser";
int capitals = 0;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c >= 'A' && c <= 'Z') {
capitals++;
}
}
double share = 100.0 * capitals / text.length();
System.out.printf("%s: %d capitals in %d characters%n",
text, capitals, text.length());
System.out.printf("%.2f percent capitals%n", share);
System.out.printf("%-8s|%5d|%n", "upper", capitals);
System.out.printf("%-8s|%5d|%n", "all", text.length());
}
}
public class Digits {
static int countDigits(String text) {
// how many characters of text are '0' to '9'
return 0;
}
static void report(String text) {
// one line, with printf
}
public static void main(String[] args) {
report("R2-D2");
report("2026-10-16");
report("hello");
}
}
public class Names {
// true when a and b are the same name, whatever
// the spaces around them and their case
static boolean same(String a, String b) {
return false;
}
// the first letter of each of the two words,
// in upper case
static String initials(String fullName) {
return "";
}
// the line for one name: see the expected output;
// the number at the end is vowels / length
static String card(String fullName) {
return "";
}
public static void main(String[] args) {
System.out.println(same("ADA", " ada"));
System.out.println(same("Ada", "Alan"));
System.out.println(initials("grace hopper"));
System.out.println(card(" Grace HOPPER "));
System.out.println(card("Alan Turing"));
}
}
public class Palindrome {
static String reversed(String text) {
// the characters of text, last to first
return text;
}
static void test(String word) {
String low = word.toLowerCase();
boolean same = low.equals(reversed(low));
System.out.println(word + ": " + same);
}
public static void main(String[] args) {
test("level");
test("Java");
test("Racecar");
}
}