Java strings
›Short versionOpen if you only have a minute.
- A string is an object. Its characters never change. Methods such as toUpperCase return a new string.
- Ignoring that return value leaves the original text as it was. Assign the result if you want the name to see it.
- Indexes start at 0 and stop at length() - 1. charAt past the end throws. indexOf returns -1 when the text is missing.
- == compares references. Two identical literals often pass, and a built or read string often fails. equals compares characters.
- substring(begin, end) includes begin and stops before end. The end index is not included.
A is how Java holds text. You will call methods on it more often than you will change a variable's type. The rule underneath those methods is : the object you already have does not edit itself.
String greeting = "Hello";
String name = "John Doe";
String empty = "";
String txt = "Hello World";
System.out.println(txt.toUpperCase());
System.out.println(txt);The first print is HELLO WORLD. The second is still Hello World. toUpperCase returned a new string, and the call threw that return value away. txt = txt.toUpperCase(); is what points txt at the new one. trim, replace, and substring work the same way.
Positions, and the index that is not a position
length() is the number of characters. The of the last character is one less than that, because the count starts at zero. "Hello" has indexes 0 through 4.
String txt = "Hello World";
System.out.println(txt.length());
System.out.println(txt.charAt(0));
System.out.println(txt.substring(0, 5));
System.out.println(txt.substring(6));
System.out.println(txt.indexOf("World"));
System.out.println(txt.indexOf("Java"));What the console shows
11 H Hello World 6 -1
substring(0, 5) stops before index 5, so the space at that index is not included. indexOf reports 6 for World and -1 for a word that is not there. Passing that -1 to charAt throws StringIndexOutOfBoundsException. So does charAt(txt.length()), which is one past the end. The last character is charAt(txt.length() - 1).
replace, contains, startsWith, endsWith, and split search or cut by characters. Each of the ones that produces text returns a new string. split(",") on "John,Jane,Bob" returns an array of the three names.
Same characters, or the same object
builds a new string and leaves the pieces alone. Comparing the result is where == stops being a shortcut.
String firstName = "John";
String lastName = "Doe";
String fullName = firstName + " " + lastName;
String built = new String("Hello");
String literal = "Hello";
System.out.println(built.equals(literal));
System.out.println(built == literal);fullName is John Doe. firstName is still John. The comparison prints true and then false. looked at the characters. == asked whether both variables refer to one object, and new String made a second one.
Two literals written as "Hello" often are the same object, so == returns true and teaches the wrong habit. Text from +, from a reader, or from new String does not make that promise. equalsIgnoreCase is the comparison that also folds capitals. If the variable on the left might be null, call equals on the literal instead: "Hello".equals(built) is false when built is null, rather than a NullPointerException.
A quote, a backslash, or a newline inside the text is an escape, the same characters as on the output page: \n, \t, \", and \\.
String txt = "Hello World"; What does txt.toUpperCase() return, and what is txt afterward if you do not assign the result?
The call returns HELLO WORLD. txt is still Hello World. The method built a new string because the original cannot be changed. The name sees the new characters only if you store that return value.