Strings
Unraveling The Mysteries

Creating Strings
Literals via assignment or passing:
String msg = "Hello";System.out.println("Hello");
String constructor:
String msg = new String("Hello");System.out.println(new String("Hello"));
The String Pool
When creating strings via literals, Java uses a cache called the String Pool.
These are the same object!
String msg = "Hello";String msg2 = "Hello";msg == msg2; // evaluates to true
But these are not:
String msg = new String("Hello");String msg2 = new String("Hello");msg == msg2; // evaluates to false
Other Ways to Create Strings
Construct from char array:
char[] msgChars = new char[]{'H', 'e', 'l', 'l', 'o'};String msg = new String(msgChars);
Construct from StringBuilder/Buffer:
StringBuilder sbld = new StringBuilder("String Builder");String s1 = new String(sbld);StringBuffer sbuf = new StringBuffer("String Buffer");String s2 = new String(sbuf);
Null String reference:
String nullStr = null;How many different String objects?
class StringCreator {
public static void main(String... args) {
String summer = new String("Summer"); // line 1
String summer2 = "Summer"; // line 2
System.out.println("Summer"); // line 3
System.out.println("autumn"); // line 4
System.out.println("autumn" == "summer"); // line 5
String autumn = new String("Summer"); // line 6
}
}Answer
5
- Line 1 creates a new String object with the value "Summer" . This object is not placed in the String constant pool.
- Line 2 creates a new String object with the value "Summer" and places it in the String constant pool.
- Line 3 doesn't need to create any new String object. It reuses the String object with the value "Summer" that already existed in the String constant pool.
- Line 4 creates a new String object with the value "autumn" and places it in the String constant pool.
- Line 5 reuses the String value "autumn" from the String constant pool. It creates a String object with the value "summer" in the String constant pool (note the difference in the case of letters—Java is case sEnSitIVe and "Summer" is not same as "summer").
-
Line 6 creates a new String object with the value "Summer".
Strings are IMMORTAL IMMUTABLE
You can't change them once they're created!
Implemented by using a private final field in the String class for internal storage, and having no mutator methods:
private final char[] value;
There's a String.toCharArray() method, but this makes a copy of the array before returning it.
Strings are zero-based
Just like arrays, the first character is number 0.
String has useful methods
A few:
- charAt(int index)
- indexOf(int ch) / indexOf(String str)
- substring(int beginIdx) / substring(int beginIdx, int endIdx);
- Second arg is end, not length!
- Length of result is (endIdx - beginIdx) -- char at endIdx is not included!
- trim()
- replace(old, new) - takes chars or strings
- length()
- startsWith(String prefix) / endsWith(String suffix)
String Methods
Remember, Strings are immutable! All these instance methods return a new String, and leave the original one untouched.
Because of this, you can chain method calls together, like so:
String result = " Sunday ".replace(' ', 'Z').trim().concat("M n");
System.out.println(result); // SundayZZM n
4.1 p186
What is the correct output?
String letters = "ABCAB";System.out.println(letters.substring(0, 2).startsWith('A'));
- true
- false
- AB
- ABC
- Compilation Error
Answer
true
Concatenation
Strings get special treatment: the + and += operators are overloaded for the String class.
These use a StringBuilder behind the scenes to do the work.
You can concatenate Strings with numbers, but remember, + is evaluated left to right. String conversion only happens when one of the operands is a String.
System.out.println(11 + 31 + "ANSWER"); // prints 42ANSWERSystem.out.println(11 + (31 + "ANSWER")); // prints 1131ANSWER
Concatenation, Cont.
Remember, += is shorthand. These two code blocks are equivalent:
String str1 = "a";str1 += "b";String str2 = "a";str2 = str2 + "b";
Comparing Strings
== compares references. It can sometimes work due to the String pool, so be careful!
In general, you should use the equals() method to compare Strings. Don't worry about optimizations - equals() has a short-circuit method to return true instantly if the Strings are actually the same reference.
The Mighty StringBuilder
Since Strings are immutable, doing concatenation generates a bunch of temporary Strings. This is horrible:
String bunchOfAs = "";for(int i = 0; i < 100; i++) {bunchOfAs += "a";}
StringBuilder is mutable, and designed for when you need to build up a string piece by piece.
StringBuilder aBuilder = new StringBuilder;for(int i = 0; i < 100; i++) {aBuilder.append("a");}String bunchOfAs = aBuilder.toString();
Building StringBuilders
- new StringBuilder();
- Creates an empty StringBuilder
- new StringBuilder(StringBuilder other)
- Initialize from another StringBuilder
- new StringBuilder(int capacity)
- If you know you're going to be building a large String, you can make things a bit faster by telling StringBuilder.
- The default capacity, at least in the Oracle JRE, is 16 characters.
- new StringBuilder(String initial)
- Create a StringBuilder which starts with an initial value
StringBuilder Methods
- append()
- Has overloads to allow appending anything
- append(Object obj) will use the value of obj.toString(), which may be overriden
- insert()
- Like append, but lets you specify where to add things
- delete(int beginIdx, int endIdx) / deleteCharAt(int idx)
- Two-param variant delete up to, but not including, endIdx
- reverse()
- Reverses the contents of the StringBuilder in-place
- replace()
- Replaces a portion of the value of the StringBuilder
- subSequence()
- Works basically the same as substring()
StringBuilder vs StringBuffer
StringBuffer is thread-safe. You can safely use the same instance in multiple threads at the same time. However, this adds some overhead.
StringBuilder is a bit faster, but not safe to share between multiple threads unless you use your own synchronization.
Strings
By mitchellmebane
Strings
- 455