Java Putting Strings Together with +, StringBuilder (JDK 1.5), and StringBuffer
Problem
You 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( ) methods. Better yet, construct and use it yourself.
Use string concatenation: the + operator. The compiler implicitly constructs a StringBuilder for you and uses its append( ) methods. Better yet, construct and use it yourself.
Explained
An object of one of the StringBuilder classes basically represents a collection of characters.
It is similar to a String object, but, as mentioned, Strings are immutable.
StringBuilders are mutable and designed for, well, building Strings. You typically
construct a StringBuilder, invoke the methods needed to get the character sequence
just the way you want it, and then call toString( ) to generate a String representing
the same character sequence for use in most of the Java API, which deals in Strings.
StringBuffer is historical—it’s been around since JDK 1.1. Some of its methods are
synchronized (see Recipe 24.5), which involves unneeded overhead in a singlethreaded
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 migrated to 1.5.
Except for the fact that StringBuilder is not threadsafe, these classes are identical
and can be used interchangeably.
The StringBuilder classes have a variety of methods for inserting, replacing, and otherwise
modifying a given StringBuilder. Conveniently, the append( ) method returns
a reference to the StringBuilder itself, so that statements like the .append(...).
append(...) are fairly common. You might even see this third way in a toString( )
method. Example 3-2 shows the three ways of concatenating strings.
. 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.
No comments:
Post a Comment