![]() |
|||
![]() ![]() |
![]() |
|
![]() |
StringBuffersJava strings are immutable; that is, a strings value may not be changed after the string is constructed. This makes strings very thread-safe and fairly fast, but also makes them excessively inefficient for many operations. For example, suppose you write String s = "one"; s += " two"; s += " three"; s += " four"; s += " five"; Compiling these statements with only immutable strings would require the construction of five separate strings: first one, then one two, then one two three, then one two three four, and finally one two three four five. Theres no way, using only strings, to create one string and then append the new parts to it. A StringBuffer is a string that can be changed. You can add additional characters to the end or the beginning or the middle of a StringBuffer without creating new objects. On the other hand, because StringBuffers are mutable, theyre not inherently thread-safe, and thus many of the methods of the StringBuffer class are synchronized. This can slow down the execution of a program when Strings arent changing. In short, the String class is optimized for strings that dont change; the StringBuffer class is optimized for strings that do change. In general, the Java compiler is fairly smart about figuring out which class to use where. Nonetheless, the more manipulation of a string youre doing, the more efficient it becomes to use a StringBuffer and convert it to a string only when youre done. The main methods of the StringBuffer class are append() and insert(). These methods are polymorphic, so they can accept any type or class of data. The append() method adds characters at the end of the StringBuffer; insert() places the new characters at a specified position in the StringBuffer. These methods are sufficiently polymorphic to handle all Java data types. There are ten different append()methods: public StringBuffer append(boolean b) public StringBuffer append(char c) public StringBuffer append(double d) public StringBuffer append(float f) public StringBuffer append(int i) public StringBuffer append(long l) public StringBuffer append(String str) public StringBuffer append(Object obj) public StringBuffer append(char str[]) public StringBuffer append(char str[], int offset, int length) Each of these methods converts its argument to a string format and appends it to the StringBuffer. The first six of these methods handles the primitive data types. Shorts and bytes are promoted to ints before conversion. Strings are also appended directly. All other object types are converted to a String object, using their toString() method, and then appended. The final append() method appends an array of chars to the StringBuffer. The second-to-last method appends the entire array, while the last method appends only the length characters in the array beginning with the character at offset. The only thing that you cannot append to a StringBuffer is an array of type other than char[]. The insert() methods are almost equally polymorphic with the exception of the methods to handle arrays of chars. These methods are public StringBuffer insert(int offset, boolean b) public StringBuffer insert(int offset, char str[]) public StringBuffer insert(int offset, double d) public StringBuffer insert(int offset, float f) public StringBuffer insert(int offset, int i) public StringBuffer insert(int offset, long l) public StringBuffer insert(int offset, Object obj) public StringBuffer insert(int offset, String str) These methods insert the string representation of their second argument beginning at the offset specified in the first argument. All characters after offset are shifted to the right. How far theyre shifted is completely dependent on the length of the string format of the second argument. Like Strings, a StringBuffer is fundamentally a private array of chars called value: private char[] value; It helps to keep this array in mind when considering where to insert an item. Because a StringBuffer is an array, the first character of the StringBuffer is number zero, not number one. Also like with Strings, the length of the value array is set when the StringBuffer object is first constructed. There are three constructors: public StringBuffer() public StringBuffer(int length) public StringBuffer(String s) The noargs constructor starts with an array of length 16. The second constructor initializes the array to the specified length. The third constructor starts with an array of length s.length() + 16 that is, the length of the string plus 16 empty spaces. This is because of the expectation that whatever length of the string that the StringBuffer initially holds, it will be expanded later. So far this is very much like the String class. The difference, however, is that the buffer can expand as necessary to hold more characters. Suppose you have the following code: StringBuffer sb = new StringBuffer(6); sb.append("Hello world!"); The string Hello world! has 12 characters. Because 12 characters is six too many for the six character StringBuffer sb, Java expands the array with the ensureCapacity() method: public synchronized void ensureCapacity(int minimumCapacity) The ensureCapacity() method expands the array to two times the current capacity plus one (2 * (capacity() + 1)) or to the requested minimum capacity, whichever is greater. A new array is allocated of the appropriate size; the old value array is copied into the new value array with the System.arrayCopy()method; and the reference is set to the new array. In code, it looks something like this: char[] value; ... char[] newValue = new char[Math.max(minimumCapacity, 2*(value.length + 1))]; System.arraycopy(value, 0, newValue, 0, value.length); value = newValue;
|
![]() |
|