Recipe 3.3 Putting Strings Together with +, StringBuilder (JDK 1.5), and StringBufferProblemYou need to put some String pieces (back) together. Solution
Use string concatenation: the
+
operator. The compiler implicitly constructs a
StringBuilder
for you and uses its
append()
Discussion
An object of one of the
StringBuilder
classes basically represents a collection of
StringBuffer
is historicalit's been around since JDK 1.1. Some of its methods are synchronized (see Recipe 24.5), which involves unneeded overhead in a single-threaded application. In 1.5, this class was "split" into
StringBuffer
(which is synchronized) and the new
StringBuilder
(which is not synchronized); thus, it is faster and preferable for single-threaded use. Another new class,
AbstractStringBuilder
, is the parent of both. In the following discussion, I'll use "the
StringBuilder
classes" to refer to all three, since they mostly have the same methods. My example code uses
StringBuffer
instead of
StringBuilder
since most people have not yet
The
StringBuilder
classes have a variety of methods for inserting, replacing, and
Example 3-2. StringBufferDemo.java
/**
* StringBufferDemo: construct the same String three different ways.
*/
public class StringBufferDemo {
public static void main(String[] argv) {
String s1 = "Hello" + ", " + "World";
System.out.println(s1);
// Build a StringBuffer, and append some things to it.
StringBuffer sb2 = new StringBuffer();
sb2.append("Hello");
sb2.append(',');
sb2.append(' ');
sb2.append("World");
// Get the StringBuffer's value as a String, and print it.
String s2 = sb2.toString();
System.out.println(s2);
// Now do the above all over again, but in a more
// concise (and typical "real-world" Java) fashion.
StringBuffer sb3 = new StringBuffer().append("Hello").
append(',').append(' ').append("World");
System.out.println(sb3.toString());
// Exercise for the reader: do it all again but without
// creating ANY temporary variables.
}
}
In fact, all the methods that modify more than one character of a StringBuilder 's contents append() , delete() , deleteCharAt() , insert() , replace() , and reverse() return a reference to the object to facilitate this style of coding. To show that StringBuilder is, as Sun claims, a (non-threadsafe) "drop-in replacement for StringBuffer ," here is StringBuilderDemo , a copy of StringBufferDemo converted to use StringBuilder . Its output is identical to StringBufferDemo :
/**
* StringBuilderDemo: construct the same String three different ways.
*/
public class StringBuilderDemo {
public static void main(String[] argv) {
String s1 = "Hello" + ", " + "World";
System.out.println(s1);
// Build a StringBuilder, and append some things to it.
StringBuilder sb2 = new StringBuilder();
sb2.append("Hello");
sb2.append(',');
sb2.append(' ');
sb2.append("World");
// Get the StringBuilder's value as a String, and print it.
String s2 = sb2.toString();
System.out.println(s2);
// Now do the above all over again, but in a more
// concise (and typical "real-world" Java) fashion.
StringBuilder sb3 = new StringBuilder().append("Hello").
append(',').append(' ').append("World");
System.out.println(sb3.toString());
}
}
As another example of using a StringBuilder , consider the need to convert a list of items into a comma-separated list, like this:
StringBuffer sb = new StringBuffer();
while (st.hasMoreElements()) {
sb.append(st.nextToken());
if (st.hasMoreElements())
sb.append(", ");
}
return sb.toString();
This pattern relies on the fact that you can call the informational method hasMoreElements() in the Enumeration (or hasNext() in an Iterator , as discussed in Recipe 7.4) more than once on each element. But it works, and it avoids getting an extra comma after the last element of the list. |