The StringBuffer Class


Synopsis


public final class StringBuffer extends Object


The Constructors for the StringBuffer class are given below.
public StringBuffer () Constructs an empty string buffer.
public StringBuffer (int i)
Constructs and empty string buffer with the specified capacity i.
public StringBuffer (String str)
Constructs a string buffer with the specified initial value String str.

Example use


The sample code below demonsrates the uses of the StringBuffer constructors.

     StringBuffer Four = new StringBuffer ("Hello World");
          StringBuffer Five = new StringBuffer (20);

Note that you can set aside an empty StringBuffer of a specified length. You can also use a string as the starting point for the string buffer.


Below are some of the methods in the StringBuffer class.
public int length ()Returnes the length (character count) of the buffer.
public synchronized void setLength (int newLength)
Sets the length of the string. If the length is reduced, characters are lost. If the length is extended the values of the new characters are set to 0.
Throws StringIndexOutOfBoundsException if the length is invalid.
public synchronized char charAt (int index)
Returns the character at the specified index (whose range is 0 to length () -1).
Throws StringIndexOutOfBoundsException if the index is invalid.
public synchronized void getChars (int srcBegin, int srcEnd, char dst [], int dstBegins)
Copies a substring of characters from this StringBuffer into the specified character array dst []. The characters of the specified substring (determined by crcBegin and srcEnd) are copied into the character array starting at the array's dstBegin location.
Throws StringIndexOutOfBoundsException if there is an invalid index into the buffer.
Also throws ArrayIndexOutOfBoundsif the destination array is overrun.
public synchronized void setCharAt (int index, char ch)
Changes the the characterat the specified index to be ch.
Throws StringIndexOutOfBoundsException if the index is invalid.
public String toString()
Constructs a String from the data in the string buffer, which can then be used in any String method.

Changing StringBuffer Contents

To change the contents of a string buffer, you can use two basic methods: append and insert.


Note - There are other forms of append and insert
(that take different arguments).

Append Example


Assume your program contains the following lines:

SringBuffer str2= new StringBuffer ("hello ");
str2.append("world");

Here is a simple method that reverses a string:

   // simple reverseString method
      publis String reverseString(String src) {
         int i, len=src.length();
         StringBuffer dest = new StringBuffer(len);

         for (i=(len - 1);i >=0; i--) {
           dest.append(src.charAt(i));
         }
         return dest.toString();
      } 

Concatenation Operators

You may recall that the + and += operators apply to strings. Both perform concatenation, and both are implemented using StringBuffer objects.

Examples

The statement

     String s = "Hi" + "there!"

is interpreted by the compiler as 

      String s = new 

         StringBuffer().append("Hi").append("there!").toString();

The statement

      s += "there!"s = new StringBuffer().append(s).append("there!").toString();


PERFORMANCE:  STRING VERSUS STRINGBUFFER.  For this tip, suppose you have
an application in which you're detabbing text for later display--using a
method like drawString in java.awt.Graphics.  In such an application, it's
necessary to go through the text character by character, and expand a tab
to the appropriate number of spaces required to reach the next tab stop
(typically set at intervals of 8 characters).

What's the fastest way to do this?  One approach is to set up an empty
string and append characters to it in turn, using the += operator for
appending, as shown in the following example:

        String result = "";

        ...

        result += 'x';

This approach works, but overlooks the fact that in Java, strings are
immutable (that is, they never change).  Therefore, the operation shown
above consists of copying the current value of "result" to a temporary
buffer, appending the character, and creating a new String object that
result then references.  Another way of saying this is that in:

        String string1 = "abc";
        String string2 = string1;

        string1 = "xyz";
        System.out.println(string2);

the printed result will be "abc," because reassigning to string1 doesn't
change the reference from string2 to the string "abc."

--- A faster approach

A much faster approach to detabbing uses StringBuffer, a class that
supports mutable strings.  Operations such as appending are directly
supported with StringBuffer, and the result can be converted to a String at
any time.

To show how this approach works in practice, here is an example of
detabbing text using String (detab1) and StringBuffer (detab2):

        public class perf {
                public static String detab1(String s)
                {
                        if (s.indexOf('\t') == -1)
                                return s;
                        String res = "";;
                        int len = s.length();
                        int pos = 0;
                        int i = 0;
                        for (; i < len && s.charAt(i) == '\t'; i++) {
                                res += "        ";
                                pos += 8;
                        }
                        for (; i < len; i++) {
                                char c = s.charAt(i);
                                if (c == '\t') {
                                        do {
                                                res += " ";
                                                pos++;
                                        } while (pos % 8 != 0);
                                }
                                else {
                                        res += c;
                                        pos++;
                                }
                        }
                        return res;
                }
      
                public static String detab2(String s)
                {
                        if (s.indexOf('\t') == -1)
                                return s;
                        StringBuffer sb = new StringBuffer();
                        int len = s.length();
                        int pos = 0;
                        int i = 0;
                        for (; i < len && s.charAt(i) == '\t'; i++) {
                                sb.append("        ");
                                pos += 8;
                        }
                        for (; i < len; i++) {
                                char c = s.charAt(i);
                                if (c == '\t') {
                                        do {
                                                sb.append(' ');
                                                pos++;
                                        } while (pos % 8 != 0);
                                }
                                else {
                                        sb.append(c);
                                        pos++;
                                }
                        }
                        return sb.toString();
                }
        
                public static String testlist[] = {
                        "",
                        "\t",
                        "\t\t\tabc",
                        "abc\tdef",
                        "1234567\t8",
                        "12345678\t9",
                        "123456789\t"
                };
        
                public static void main(String args[])
                {
                        for (int i = 0; i < testlist.length; i++) {
                                String tc = testlist[i];
                                if (!detab1(tc).equals(detab2(tc)))
                                        System.err.println(tc);
                        }
        
                        String test_string =
                            "\t\tthis is a test\tof detabbing performance";
                        int N = 5000;
                        int i = 0;
        
                        long ct = System.currentTimeMillis();
                        for (i = 1; i <= N; i++)
                                detab1(test_string);
                        long elapsed = System.currentTimeMillis() - ct;
                        System.out.println("String time = " + elapsed);
        
                        ct = System.currentTimeMillis();
                        for (i = 1; i <= N; i++)
                                detab2(test_string);
                        elapsed = System.currentTimeMillis() - ct;
                        System.out.println("StringBuffer time = " + elapsed);
                }
        }

This example first runs some test data through both methods to ensure they
are equivalent, and then does a timing to compare the two.  The second
method, using StringBuffer, runs approximately six times as fast as the
first method using String.

When you're tuning programs that do a lot of character processing, it's
always a good idea to keep an eye on how much work the program is doing for
each character, and the example given above illustrates how character data
in the Java language can be efficiently manipulated.

Back to Java School