Text, and the String methods
Strings are objects, so they come with methods: counting characters, reading one, cutting a piece out — and why == is not equals.
A string is an object
A String holds a run of characters. It is not a primitive, so it carries methods with it: ask a string how long it is, ask for the character at a place, ask for a piece of it, and it answers. Every one of those answers is a new value; the original string is untouched.
Positions start at zero. In "ada lovelace" the first character sits at position 0, the space sits at 3, and the length is 12 — one more than the last position. Nearly every off-by-one puzzle in text comes back to this rule.
The methods you will use weekly
length() counts the characters. charAt(0) reads a single one. substring(0, 3) copies a range: the first position is included and the last is not, so it takes three characters and stops. toUpperCase() and toLowerCase() hand back a new string in the other case.
indexOf(" ") reports where a piece sits, or -1 when it is not there at all. replace swaps one piece for another, and trim strips the spaces from both ends — the usual repair for text a person typed.
Comparing text, and the double equals trap
The double equals sign asks whether two names point at the same object, not whether the text matches. Two identical strings produced in different ways are two separate objects, so == says false while equals says true. This catches out almost everyone once.
Compare text with equals, or with equalsIgnoreCase when letter case should not matter. The double equals sign keeps its ordinary meaning for numbers, where it compares the values themselves.
Text is built from pieces
A string is immutable: every method that seems to change it returns a new string instead. name.toUpperCase() on a line by itself does the work and throws the answer away. Assign it or print it.
Concatenation with + builds a new string too. In a loop this can be expensive, because each turn copies the text so far; for a handful of lines it is perfect, and for thousands a StringBuilder is the tool. The reason is the same: strings do not change, so joining two makes a third.
Joining and formatting
Three methods save you from writing the plus sign over and over. String.join(", ", parts) takes a separator and a group of strings and puts the separator between them, so a list of tags becomes one line without a trailing comma to trim. String.format("%s scored %d", name, score) builds a line from a template, and System.out.printf does the same and prints it. The letters after the percent sign choose the shape: %s for text, %d for a whole number, %.2f for a number with two decimal places, and %n for a line break.
The template is worth knowing because it keeps the sentence in one piece. With plus signs, the words and the values are interleaved and a missing space is hard to see. With a template, the sentence is one string and the values follow it in order, so a reader can check the wording without reading the variables at all.
Characters, codes and quotes
charAt gives a char, which is a single character and not a string. "a" is text and 'a' is a char. Adding a char to a number uses its character code; cast the result back with (char) to see the letter.
Some characters need an escape. \n is a new line, \t is a tab, and a backslash before a quote lets the quote sit inside the string instead of ending it. The compiler turns the pair into one character in the value.
Because a char is a primitive, the double equals sign compares two of them by their character code, and that is correct. The rule about equals applies to String only: two chars are values, while two strings are objects. It is worth keeping those two facts apart, because the same sign means two different things one line apart.
Length, pieces, case and comparison
String name = "ada lovelace";
System.out.println(name.length()); // 12
System.out.println(name.charAt(0)); // a
System.out.println(name.substring(0, 3)); // ada
System.out.println(name.toUpperCase()); // ADA LOVELACE
System.out.println(name.indexOf(" ")); // 3
System.out.println(name.replace("ada", "Grace"));
String typed = "java";
String copy = new String("java");
System.out.println(typed == copy); // false
System.out.println(typed.equals(copy)); // trueThe same string, asked five questions
Press Run and match each line to the method that produced it. Then print the length of your own name, and compare two strings you build in different ways.
Three string traps: == compares object identity, so use equals; indexes run from 0 to length() - 1, so charAt(length()) throws; and substring(start, end) excludes the end. A fourth, quieter one: indexOf returns -1 when the piece is absent, which is not a valid index.
Try these next
- Take a full name with messy spaces, trim it, and print the first and last name separately.
- Print the same sentence in upper case, lower case, and with its first letter capitalised by hand.
- Ask for a word that is not there with
indexOf, then guard the result before using it as an index.
A name badge from messy input
Press Run and follow how one trimmed string becomes four values. Then change the name to one with three parts, and decide which part your code should treat as the last name.
Strings never change. A method such as toUpperCase() returns a new string and leaves the old one alone, so calling it on a line by itself achieves nothing — keep the answer or print it.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
How do you check whether two strings hold the same text?
