Section 7.5. From the Java Library: java.lang.StringBuffer


[Page 317 (continued)]

7.5. From the Java Library: java.lang.StringBuffer

One problem with the keywordSearch() method is that it is not very efficient because a String in Java is a read-only object. This means that a String cannot be changed once it has been instantiated. You cannot insert new characters or delete existing characters.

java.sun.com/docs


Java Language Rule: Strings Are Immutable

Once instantiated, a Java String cannot be altered in any way.


Given this fact, how is it possible that the resultStr in the keywordSearch() ends up with the correct value? The answer is that every time we assign a new value to resultStr, Java has to create a new String object. Figure 7.9 illustrates the process. Thus, given the statement

Figure 7.9. Evaluating resultStr = resultStr + ptr + " " creates an orphan object that must be garbage collected.
(This item is displayed on page 318 in the print version)


resultStr = resultStr + ptr + " "; 


Java will evaluate the right-hand side, which creates a new String object whose value would be the concatenation of the right-hand-side elements, resultStr + ptr + " " (Fig. 7.9a). It would then assign the new object as the new referent of resultStr (Fig. 7.9b). This turns the previous referent of resultStr into an orphan objectthat is, an object that no longer has any references to it. Java will eventually dispose of these orphaned objects, removing them from memory in a process known as garbage collection. However, creating and disposing of objects is a task that consumes the computer's time.

The fact that this assignment statement occurs within a loop means that several new objects are created and later garbage collected. Because object creation is a relatively time-consuming and memory-consuming operation, this algorithm is somewhat wasteful of Java's resources.


[Page 318]

Of course, except for the inefficiency of doing it this way, no real harm is done by using this algorithm in the keywordSearch() method. Java's garbage collector will automatically reclaim the memory used by the orphaned object. However, this algorithm does consume more of Java's resources than other algorithms we might use.

Java Language Rule: Automatic Garbage Collection

An object that has no reference to it can no longer be used in a program. Therefore, Java will automatically get rid of it. This is known as garbage collection.


A more efficient way to write the keywordSearch() method would make use of a StringBuffer to store and construct the resultStr. Like the String class, the java.lang.StringBuffer class also represents a string of characters. However, unlike the String class, a StringBuffer can be modified, and it can grow and shrink in length as necessary. As Figure 7.10 shows, the StringBuffer class contains several of the same kinds of methods as the String classfor example, charAt() and length(). But it also contains methods that allow characters and other types of data to be inserted into a string, such as append(), insert(), and setCharAt(). Most string-processing algorithms use StringBuffers instead of Strings as their preferred data structure.

Figure 7.10. The java.lang.StringBuffer class.
(This item is displayed on page 319 in the print version)


Choosing the appropriate data structure


Java Programming Tip: StringBuffer

A StringBuffer should be used instead of a String for any task that involves modifying a string.


The StringBuffer class provides several methods that are useful for string processing. The constructor method, StringBuffer(String), makes it easy to convert a String into a StringBuffer. Similarly, once you are done processing the buffer, the toString() method makes it easy to convert a StringBuffer back into a String.


[Page 319]

The typical way to use a StringBuffer is shown in the following revised version of the keywordSearch() method:

public String keywordSearch(String s, String keyword) { // Create StringBuffer   StringBuffer resultStr = new StringBuffer();   int count = 0;   int ptr = s.indexOf(keyword);   while (ptr != -1) {     ++count;     resultStr.append(ptr + " ");                       // Append to buffer     ptr = s.indexOf(keyword, ptr + 1);   }   resultStr.insert(0, count + ": ");   return resultStr.toString();                         // Convert buffer to String } // keywordSearch() 


We declare resultStr as a StringBuffer instead of a String. Then, instead of concatenating the ptr and reassigning the resultStr, we append() the ptr to the resultStr for each occurrence of a keyword. Similarly, after the loop exits, we insert() the count at the front (index 0) of the resultStr. Finally, we convert resultStr into a String by using the toString() method before returning the method's result.

One advantage of the StringBuffer class is that there are several versions of its insert() and append() methods. These make it possible to insert any type of dataint, double, Object, and so oninto a StringBuffer. The method itself takes care of converting the data into a string for us.

To summarize, String objects in Java are immutable. So when a String is "modified," this really means that a new String object is created and the old String object must be garbage collected. This is somewhat inefficient, especially if done repeatedly within a loop. To avoid these inefficiencies, use a StringBuffer instead of a String in such contexts.

Strings are immutable





Java, Java, Java(c) Object-Orienting Problem Solving
Java, Java, Java, Object-Oriented Problem Solving (3rd Edition)
ISBN: 0131474340
EAN: 2147483647
Year: 2005
Pages: 275

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net