Class StringBuffer
Once a String object is created, its contents can never change. We now discuss the features of class StringBuffer for creating and manipulating dynamic string informationthat is, modifiable strings. Every StringBuffer is capable of storing a number of characters specified by its capacity. If the capacity of a StringBuffer is exceeded, the capacity is automatically expanded to accommodate the additional characters. Class StringBuffer is also used to implement operators + and += for String concatenation.
Performance Tip 29.2
Java can perform certain optimizations involving String objects (such as sharing one String object among multiple references) because it knows these objects will not change. Strings (not StringBuffers) should be used if the data will not change. |
Performance Tip 29.3
In programs that frequently perform string concatenation, or other string modifications, it is more efficient to implement the modifications with class StringBuffer (covered in Section 29.4.1 ). |
29.4.1. StringBuffer Constructors
Class StringBuffer provides four constructors. Three of these constructors are demonstrated in Fig. 29.10. Line 8 uses the no-argument StringBuffer constructor to create a StringBuffer with no characters in it and an initial capacity of 16 characters (the default for a StringBuffer). Line 9 uses the StringBuffer constructor that takes an integer argument to create a StringBuffer with no characters in it and the initial capacity specified by the integer argument (i.e., 10). Line 10 uses the StringBuffer constructor that takes a String argument (in this case, a string literal) to create a StringBuffer containing the characters in the String argument. The initial capacity is the number of characters in the String argument plus 16.
Figure 29.10. StringBuffer class constructors.
1 // Fig. 29.10: StringBufferConstructors.java 2 // StringBuffer constructors. 3 4 public class StringBufferConstructors 5 { 6 public static void main( String args[] ) 7 { 8 StringBuffer buffer1 = new StringBuffer(); 9 StringBuffer buffer2 = new StringBuffer( 10 ); 10 StringBuffer buffer3 = new StringBuffer( "hello" ); 11 12 System.out.printf( "buffer1 = "%s" ", buffer1.toString() ); 13 System.out.printf( "buffer2 = "%s" ", buffer2.toString() ); 14 System.out.printf( "buffer3 = "%s" ", buffer3.toString() ); 15 } // end main 16 } // end class StringBufferConstructors
|
The statements on lines 1214 uses StringBuffer method toString to output the StringBuffer with the printf method. In Section 29.4.4, we discuss how Java uses StringBuffer objects to implement the + and += operators for string concatenation.
29.4.2. StringBuffer Methods length, capacity, setLength and ensureCapacity
Class StringBuffer provides methods length and capacity to return the number of characters currently in a StringBuffer and the number of characters that can be stored in a StringBuffer without allocating more memory, respectively. Method ensureCapacity guarantees that a StringBuffer has at least the specified capacity. Method setLength increases or decreases the length of a StringBuffer. The application in Fig. 29.11 demonstrates these methods.
Figure 29.11. StringBuffer methods length and capacity.
(This item is displayed on page 1367 in the print version)
1 // Fig. 29.11: StringBufferCapLen.java 2 // StringBuffer length, setLength, capacity and ensureCapacity methods. 3 4 public class StringBufferCapLen 5 { 6 public static void main( String args[] ) 7 { 8 StringBuffer buffer = new StringBuffer( "Hello, how are you?" ); 9 10 System.out.printf( "buffer = %s length = %d capacity = %d ", 11 buffer.toString(), buffer.length(), buffer.capacity() ); 12 13 buffer.ensureCapacity( 75 ); 14 System.out.printf( "New capacity = %d ", buffer.capacity() ); 15 16 buffer.setLength( 10 ); 17 System.out.printf( "New length = %d buf = %s ", 18 buffer.length(), buffer.toString() ); 19 } // end main 20 } // end class StringBufferCapLen
|
The application contains one StringBuffer called buffer. Line 8 uses the StringBuffer constructor that takes a String argument to initialize the StringBuffer with "Hello, how are you?". Lines 1011 print the contents, length and capacity of the StringBuffer. Note in the output window that the capacity of the StringBuffer is initially 35. Recall that the StringBuffer constructor that takes a String argument initializes the capacity to the length of the string passed as an argument plus 16.
Line 13 uses method ensureCapacity to expand the capacity of the StringBuffer to a minimum of 75 characters. Actually, if the original capacity is less than the argument, the method ensures a capacity that is the greater of the number specified as an argument and twice the original capacity plus 2. The StringBuffer's current capacity remains unchanged if it is more than the specified capacity.
Performance Tip 29.4
Dynamically increasing the capacity of a StringBuffer can take a relatively long time. Executing a large number of these operations can degrade the performance of an application. If a StringBuffer is going to increase greatly in size, possibly multiple times, setting its capacity high at the beginning will increase performance. |
Line 16 uses method setLength to set the length of the StringBuffer to 10. If the specified length is less than the current number of characters in the StringBuffer, the buffer is truncated to the specified length (i.e., the characters in the StringBuffer after the specified length are discarded). If the specified length is greater than the number of characters currently in the StringBuffer, null characters (characters with the numeric representation 0) are appended to the StringBuffer until the total number of characters in the StringBuffer is equal to the specified length. See Section 14.7.1 for more details.
29.4.3. StringBuffer Methods charAt, setCharAt, getChars and reverse
Class StringBuffer provides methods charAt, setCharAt, getChars and reverse to manipulate the characters in a StringBuffer. Each of these methods is demonstrated in Fig. 29.12.
Figure 29.12. StringBuffer class character-manipulation methods.
1 // Fig. 29.12: StringBufferChars.java 2 // StringBuffer methods charAt, setCharAt, getChars and reverse. 3 4 public class StringBufferChars 5 { 6 public static void main( String args[] ) 7 { 8 StringBuffer buffer = new StringBuffer( "hello there" ); 9 10 System.out.printf( "buffer = %s ", buffer.toString() ); 11 System.out.printf( "Character at 0: %s Character at 4: %s ", 12 buffer.charAt( 0 ), buffer.charAt( 4 ) ); 13 14 char charArray[] = new char[ buffer.length() ]; 15 buffer.getChars( 0, buffer.length(), charArray, 0 ); 16 System.out.print( "The characters are: " ); 17 18 for ( char character : charArray ) 19 System.out.print( character ); 20 21 buffer.setCharAt( 0, 'H' ); 22 buffer.setCharAt( 6, 'T' ); 23 System.out.printf( " buf = %s", buffer.toString() ); 24 25 buffer.reverse(); 26 System.out.printf( " buf = %s ", buffer.toString() ); 27 } // end main 28 } // end class StringBufferChars
|
Method charAt (line 12) takes an integer argument and returns the character in the StringBuffer at that index. Method getChars (line 15) copies characters from a StringBuffer into the character array passed as an argument. This method takes four argumentsthe starting index from which characters should be copied in the StringBuffer, the index one past the last character to be copied from the StringBuffer, the character array into which the characters are to be copied and the starting location in the character array where the first character should be placed. Method setCharAt (lines 21 and 22) takes an integer and a character argument and sets the character at the specified position in the StringBuffer to the character argument. Method reverse (line 25) reverses the contents of the StringBuffer.
Common Programming Error 29.3
Attempting to access a character that is outside the bounds of a StringBuffer (i.e., with an index less than 0 or greater than or equal to the StringBuffer's length) results in a StringIndexOutOfBoundsException. |
29.4.4. StringBuffer append Methods
Class StringBuffer provides overloaded append methods to allow values of various types to be appended to the end of a StringBuffer. Versions are provided for each of the primitive types and for character arrays, Strings, Objects, StringBuffers and CharSequences. (Remember that method toString produces a string representation of any Object.) Each of the methods takes its argument, converts it to a string and appends it to the StringBuffer. The append methods are demonstrated in Fig. 29.13.
Figure 29.13. StringBuffer class append methods.
(This item is displayed on pages 1370 - 1371 in the print version)
1 // Fig. 29.13: StringBufferAppend.java 2 // StringBuffer append methods. 3 4 public class StringBufferAppend 5 { 6 public static void main( String args[] ) 7 { 8 Object objectRef = "hello"; 9 String string = "goodbye"; 10 char charArray[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; 11 boolean booleanValue = true; 12 char characterValue = 'Z'; 13 int integerValue = 7; 14 long longValue = 10000000000L; 15 float floatValue = 2.5f; // f suffix indicates 2.5 is a float 16 double doubleValue = 33.333; 17 18 StringBuffer lastBuffer = new StringBuffer( "last StringBuffer" ); 19 StringBuffer buffer = new StringBuffer(); 20 21 buffer.append( objectRef ); 22 buffer.append( " " ); // each of these contains new line 23 buffer.append( string ); 24 buffer.append( " " ); 25 buffer.append( charArray ); 26 buffer.append( " " ); 27 buffer.append( charArray, 0, 3 ); 28 buffer.append( " " ); 29 buffer.append( booleanValue ); 30 buffer.append( " " ); 31 buffer.append( characterValue ); 32 buffer.append( " " ); 33 buffer.append( integerValue ); 34 buffer.append( " " ); 35 buffer.append( longValue ); 36 buffer.append( " " ); 37 buffer.append( floatValue ); 38 buffer.append( " " ); 39 buffer.append( doubleValue ); 40 buffer.append( " " ); 41 buffer.append( lastBuffer 42 43 System.out.printf( "buffer contains %s ", buffer.toString() ); 44 } // end main 45 } // end StringBufferAppend
|
Actually, StringBuffers and the append methods are used by the compiler to implement the + and += operators for String concatenation. For example, assuming the declarations
String string1 = "hello"; String string2 = "BC"; int value = 22;
the statement
String s = string1 + string2 + value;
concatenates "hello", "BC" and 22. The concatenation is performed as follows:
new StringBuffer().append( "hello" ).append( "BC" ).append( 22 ).toString();
First, Java creates an empty StringBuffer, then appends to the StringBuffer the string "hello", the string "BC" and the integer 22. Next, StringBuffer's method toString converts the StringBuffer to a String object to be assigned to String s. The statement
s += "!";
is performed as follows:
s = new StringBuffer().append( s ).append( "!" ).toString();
First, Java creates an empty StringBuffer, then appends to the StringBuffer the current contents of s followed by "!". Next, StringBuffer's method toString converts the StringBuffer to a string representation and the result is assigned to s.
29.4.5. StringBuffer Insertion and Deletion Methods
Class StringBuffer provides overloaded insert methods to allow values of various types to be inserted at any position in a StringBuffer. Versions are provided for each of the primitive types and for character arrays, Strings, Objects and CharSequences. Each of the methods takes its second argument, converts it to a string and inserts it immediately preceding the index specified by the first argument. The index specified by the first argument must be greater than or equal to 0 and less than the length of the StringBufferotherwise, a StringIndexOutOfBoundsException occurs. Class StringBuffer also provides methods delete and deleteCharAt for deleting characters at any position in a StringBuffer. Method delete takes two argumentsthe starting index and the index one past the end of the characters to delete. All characters beginning at the starting index up to but not including the ending index are deleted. Method deleteCharAt takes one argumentthe index of the character to delete. Invalid indices cause both methods to throw a String-IndexOutOfBoundsException. Methods insert, delete and deleteCharAt are demonstrated in Fig. 29.14.
Figure 29.14. StringBuffer methods insert and delete.
(This item is displayed on pages 1371 - 1372 in the print version)
1 // Fig. 29.14: StringBufferInsert.java 2 // StringBuffer methods insert, delete and deleteCharAt. 3 4 public class StringBufferInsert 5 { 6 public static void main( String args[] ) 7 { 8 Object objectRef = "hello"; 9 String string = "goodbye"; 10 char charArray[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; 11 boolean booleanValue = true; 12 char characterValue = 'K'; 13 int integerValue = 7; 14 long longValue = 10000000; 15 float floatValue = 2.5f; // f suffix indicates that 2.5 is a float 16 double doubleValue = 33.333; 17 18 StringBuffer buffer = new StringBuffer(); 19 20 buffer.insert( 0, objectRef ); 21 buffer.insert( 0, " " ); // each of these contains two spaces 22 buffer.insert( 0, string ); 23 buffer.insert( 0, " " ); 24 buffer.insert( 0, charArray ); 25 buffer.insert( 0, " " ); 26 buffer.insert( 0, charArray, 3, 3 ); 27 buffer.insert( 0, " " ); 28 buffer.insert( 0, booleanValue ); 29 buffer.insert( 0, " " ); 30 buffer.insert( 0, characterValue ); 31 buffer.insert( 0, " " ); 32 buffer.insert( 0, integerValue ); 33 buffer.insert( 0, " " ); 34 buffer.insert( 0, longValue ); 35 buffer.insert( 0, " " ); 36 buffer.insert( 0, floatValue ); 37 buffer.insert( 0, " " ); 38 buffer.insert( 0, doubleValue ); 39 40 System.out.printf( 41 "buffer after inserts: %s ", buffer.toString() ); 42 43 buffer.deleteCharAt( 10 ); // delete 5 in 2.5 44 buffer.delete( 2, 6 ); // delete .333 in 33.333 45 46 System.out.printf( 47 "buffer after deletes: %s ", buffer.toString() ); 48 } // end main 49 } // end class StringBufferInsert
|