Step 1 of 7 · Reading · ~3 min
Learn
Strings
Strings
String is a class, not a primitive, and its objects are immutable: no method ever changes a string, it returns a new one. By the end of this lesson you can slice a string apart by position, compare strings correctly, and build one up without wasting work.
Position-based tools
Characters are numbered from 0. length() is the count, charAt(i) is one character, indexOf finds where something starts (or returns -1), and substring cuts a piece out:
String file = "report.final.pdf";
file.length(); // 16
file.charAt(0); // 'r' (a char, not a String)
file.lastIndexOf('.'); // 12, the LAST dot
file.substring(13); // "pdf" -- from index 13 to the end
file.substring(0, 6); // "report" -- start inclusive, end EXCLUSIVE
The idiom for "everything after a separator" is substring(indexOf(sep) + 1):
String mail = "[email protected]";
int at = mail.indexOf('@'); // 3
mail.substring(0, at); // "sam"
mail.substring(at + 1); // "example.org"
Skipping the + 1 would keep the separator itself: substring(at) is "@example.org".
Immutability: use the returned value
String t = "java";
t.toUpperCase(); // result thrown away
System.out.println(t); // java -- unchanged
t = t.toUpperCase(); // keep the new string
System.out.println(t); // JAVA
This is the most common beginner bug in the language: calling a string method as a statement and expecting the variable to change. Other methods that return new strings: toLowerCase(), trim() (strips spaces from both ends), replace(a, b), repeat(n).
Comparing: equals, not ==
String a = "hello";
String c = new String("hello");
System.out.println(a == c); // false: two different objects
System.out.println(a.equals(c)); // true: same characters
== asks "are these the same object?"; equals asks "do they hold the same text?". Always use equals (or equalsIgnoreCase) for content. If the left side might be null, s.equals(x) crashes with NullPointerException; Objects.equals(s, x) does not.
chars are numbers
A char is a 16-bit number that prints as a character. Adding two of them adds the numbers:
"Hello".charAt(1) + "Hello".charAt(2); // 209, an int: 'e' (101) + 'l' (108)
"Hello".charAt(1) + ""; // "e", a String
To join characters, join strings: "" + c1 + c2, or use a StringBuilder.
Splitting and building
split(regex) returns an array of pieces. "a,b,c".split(",") is ["a", "b", "c"]; trailing empty pieces are dropped, so "a,b,,".split(",").length is 2.
Concatenating with += creates a new string every time it runs, so doing it over and over (as the loops lesson will let you) wastes work. A StringBuilder edits one buffer:
StringBuilder sb = new StringBuilder();
sb.append(1).append('-');
sb.append(2).append('-');
sb.append(3).append('-');
sb.reverse(); // in place
System.out.println(sb); // -3-2-1
toString() converts a builder back to a String when you need one.
Common mistakes
- Ignoring the return value, so
s.trim();does nothing visible. ==between strings. It sometimes appears to work because of literal sharing, then fails on input read at runtime.- Treating the end index of
substringas inclusive.substring(0, 5)has 5 characters. - Calling
charAt(i)orsubstringout of range, which throwsStringIndexOutOfBoundsException. ValidcharAtindexes are0tolength() - 1.
Your exercise
Reformat a person's name for a class list: surname in capitals, a comma, then the first initial. You will need to find the space, cut on either side of it, and clean up capitalization and stray spaces at the ends of the line. Remember that every string method returns a new string.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…