|
|
Using the String class to represent string data is all very well. However, if you have a program that needs to run at a desired speed, like a game, then preferably all of the memory required would be allocated before the main game loop begins, as allocating new memory and deallocating old memory can use up processor time/power. This can affect the speed of your programs. In many circumstances you cannot help but create new objects on the fly that are required for a dynamically running program, but sometimes there are alternatives. Creating new instances of objects is something that you will come across when programming in Java. The key is to know when to create a new object and when it is more efficient to keep the one you have and simply change the data inside it, which is important for processor-intensive programs, such as games.
When using a String object, any changes to the data mean creating a new String object containing the required changes. The StringBuffer is mutable (the data can be modified), which means that you can use the same object and simply change its contents; you can also handle the amount of memory set aside for the data, as we shall see in due course. The StringBuffer class is a member of the package java.lang similar to the String class and is therefore also readily available for you to use in your code.
There are three constructors for the StringBuffer class: StringBuffer(), StringBuffer(int length), and StringBuffer (String str).
The first constructor, StringBuffer(), takes no parameters, creating a new StringBuffer object with no string value and a buffer capacity of 16 characters. The string buffer is preallocated memory for the character data of the string to be stored. The buffer capacity is therefore the number of characters that memory is currently allocated to store.
StringBuffer myStrBuf = new StringBuffer();
The second constructor, StringBuffer(int length), creates a new StringBuffer object containing no characters and allocates a buffer of the capacity equal to the value of the argument length.
StringBuffer myStrBuf = new StringBuffer(50);
This code creates a new StringBuffer object with a buffer capacity of 50.
The third constructor, StringBuffer(String str), creates a new StringBuffer object containing the character values equal to those in the String argument str.
StringBuffer myStrBuf = new StringBuffer("Hello World"); System.out.println("Length = " + myStrBuf.length()); // length equals 11 System.out.println("Capacity = " + myStrBuf.capacity()); // capacity equals 11 + 16 = 27
This code first creates a new StringBuffer containing the character sequence "Hello World." Here the capacity of the string buffer is initialized to the length of the string argument str, plus 16.
The second line of code simply prints the length of the string data currently contained in the newly created StringBuffer object to the console screen. For this, the method length, a member of the StringBuffer object, is invoked with the value returned, as we saw for String objects that contain a similar method.
The last line of code prints out the current capacity of the string buffer by invoking the method capacity; we will look at the length and capacity of StringBuffer objects a little later in this section.
The method toString returns a String object representing the data contained in the object to which it belongs. The method toString is a member of all classes in Java, as all classes are derived from the class Object from which the method toString belongs. Even the String class contains the method toString, which simply returns itself. Do not worry about this fact for now, as it will be fully explained in Chapter 4. For the time being, all you need to know is that the method toString is a member of the StringBuffer class, which returns a newly created String object containing the text equal to that which is contained in the StringBuffer object.
StringBuffer myStrBuf = new StringBuffer("Hello World"); String myStr = myStrBuf.toString();
By creating a String object representation of a StringBuffer object, you can manipulate the data as a String object using String object methods.
String anotherString = "Hello World"; if(myStr.equals(anotherString)) System.out.println("string values are equal");
This code illustrates a solution if you have a StringBuffer object and you want to test if its string data is equal to that of a String object. A method that is new to Java 1.4 is the method contentEquals, a member of the String class, which returns true if the characters in the String object are equal to those contained in the StringBuffer argument. So the previous code could also be implemented as follows:
StringBuffer myStrBuf = new StringBuffer("Hello World"); String anotherString = "Hello World"; if(anotherString.contentEquals(myStrBuf)) System.out.println("string values are equal");
If you are looking to perform certain string operations on a StringBuffer object and cannot find the method to perform this task in the StringBuffer class, chances are you will need to create a String object representation of the data and use a suitable method found in the String class instead.
We will now look at altering the character values of a StringBuffer object. The simplest method for this is the method setCharAt. This method takes two parameters. The first is the index position of the character to be replaced and the second is the new replacement character.
StringBuffer myStrBuf = new StringBuffer("Beware of the beast"); myStrBuf.setCharAt(15, 'l'); // myStrBuf now equals "Beware of the blast"
The StringBuffer class contains the method charAt similar to the String class for retrieving the character at a given index position that is passed as a parameter to the method.
The method append is used to add a value onto the end of the current value contained in the StringBuffer object and is overloaded to accept all of the different data types.
StringBuffer myStrBuf = new StringBuffer("I hate"); myStrBuf.append(" broccoli"); myStrBuf.append(" a lot");
The value of the text contained in the StringBuffer object referenced by myStrBuf will now equal "I hate broccoli a lot." Variables of any data type can be added too.
int value = 22; StringBuffer myStrBuf = new StringBuffer("Value = "); myStrBuf.append(value);
The method insert will insert, at a specified position in the string buffer, a string representation of a specified value. Again, this method is overloaded to accept all of the different data types.
StringBuffer myStrBuf = new StringBuffer("I ate broccoli"); myStrBuf.insert(2, 'h');
This code inserts the character h into the string buffer at index position 2, giving the StringBuffer object the string value "I hate broccoli." The insertion does not replace characters but simply moves the remaining characters along. The methods append and insert both increase the capacity of the string buffer by the length, in characters, of the argument.
In order to replace characters, you can use the method replace, which takes three parameters: the start index of the region that is to be replaced, the end index of the region that is to be replaced (both of type int), and the replacement string of type String.
StringBuffer myStrBuf = new StringBuffer("I adore broccoli"); myStrBuf.replace(2, 7, "hate");
This code will replace the word "adore" with the word "hate." The words are of different lengths to illustrate that you may replace larger sections of text with smaller sections and vice versa.
If you just want to remove a section of characters from the string buffer, the methods delete and deleteCharAt can be used. The delete method simply takes two parameters: a start index and end index for the section of the string buffer that you wish to be removed.
StringBuffer myStrBuf = new StringBuffer("I do not hate broccoli"); myStrBuf.delete(2,9);
This code removes the characters "do not " (removing a space on the end also) from the string buffer, leaving the string value "I hate broccoli" once again. The method deleteCharAt takes one parameter, which is simply the index position in the string buffer of the character that you wish to remove.
The Broccoli.java example continues to remove the first character from a StringBuffer object initially containing the text "I hate broccoli", each time printing the remaining characters in the string buffer to the console screen. Here is the code:
public class Broccoli { public static void main(String args[]) { StringBuffer myStrBuf = new StringBuffer("I hate broccoli"); while(myStrBuf.length() > 0) { System.out.println(myStrBuf); myStrBuf.deleteCharAt(0); } } }
When you compile and run this code, you should get output similar to the following screen shot.
Figure 3-10:
As you can see, each time the code block for the while loop is executed, the first character in the string buffer is removed. When printed each time on a new line, the original text "I hate broccoli" eventually reads down, as well as across.
Just to differentiate, the length of a StringBuffer object refers to the number of characters, whereas the capacity refers to the size of the string buffer (the allocated memory slots where characters can be placed) in the StringBuffer object. The method setLength can be used to set the length of the character string in the StringBuffer object, taking a parameter of type int as the new length.
StringBuffer myStrBuf = new StringBuffer("Hello World"); myStrBuf.setLength(5); // now equal to "Hello"
If the new length is less than the current length, the value is truncated to the specified size. If the length is increased, then for every new character, a null character (in Unicode, \u0000) is appended to the string.
The method ensureCapacity will set the capacity of the string buffer to a minimum capacity to which it will not fall under, taking a parameter of type int as the minimum capacity. This means that you can set up your StringBuffer object so that it will not need to allocate any more memory if you know the maximum amount of memory that you will require. Suppose you know that your string data will never exceed 100 characters; you can simply ensure that the capacity of the string buffer is always a minimum of 100 from the beginning.
Note | When calling ensureCapacity, the capacity is actually set to the greater of either the argument value or the current capacity of the string buffer multiplied by 2, plus 2. |
|
|