Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

It was a interview question. I was asked to implement StringBuffer append function. I saw the code after interview. But I cannot understand how the operation is done with creation of a single object.

I am thinking like this.

String s = "orange";
s.append("apple");

here two objects are created.

But

StringBuilder s = new StringBuilder("Orange");
s.append("apple");

Now here only one object is created.

How is java doing this operation?

share|improve this question
    
There are a few assumptions in the question which are not correct. new StringBuilder() and new String() creates two objects. –  Peter Lawrey Nov 4 '11 at 15:14
2  
Was it my question? ;) –  Adam Dray Aug 23 '13 at 18:46
add comment

9 Answers

up vote 14 down vote accepted

First there is a problem with your question:

String s = "orange";
s.append("apple");

here two objects are created

Correct, two Objects are created, the String "orange" and the String "apple", inside the StringBuffer/StringBuilder no Objects will be created if we don't overflow the buffer. So those lines of code create 2 or 3 objects.

StringBuilder s = new StringBuilder("Orange");
s.append("apple");

Now here only one object is created

I don't know where you get that, here you create one StringBuilder Object, one "Orange" String, one "apple" String, for a total of 3 Objects, or 4 if we overflow the StringBuilder buffer. (I count the array creation as object creation).


I read your question as, how can StringBuilder do the append without creating a new Object (when the buffer is not overflown)?

You should look at StringBuilder, since it's the non thread safe implementation. The code is interesting and easy to read. I've added the inline comments.

As internal structure there is a char array, not a String. It is initially built with length 16 and will be increased every time the capacity is exceeded. If the Strings to append fit within the char array, there is no need to create new Objects.

StringBuilder extends AbstractStringBuilder, where you'll find the following code:

/**
 * The value is used for character storage.
 */
char value[];

Since not all the array will be used at a given time, another important variable is the length:

/**  
 * The count is the number of characters used.
 */
int count;

There are many overloading of append, but the most interesting one is the following:

public AbstractStringBuilder append(String str) {
    if (str == null) str = "null"; //will literally append "null" in case of null
    int len = str.length(); //get the string length
    if (len == 0) return this; //if it's zero, I'm done
    int newCount = count + len; //tentative new length
    if (newCount > value.length) //would the new length fit?
        expandCapacity(newCount); //oops, no, resize my array
    str.getChars(0, len, value, count); //now it will fit, copy the chars 
    count = newCount; //update the count
    return this; //return a reference to myself to allow chaining
}

String.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) Copies characters from this string into the destination character array.

So, the append method is quite simple, the only magic left to discover is the expandCapacity, here it is:

void expandCapacity(int minimumCapacity) {
    //get the current length add one and double it
    int newCapacity = (value.length + 1) * 2; 
    if (newCapacity < 0) { //if we had an integer overflow
        newCapacity = Integer.MAX_VALUE; //just use the max positive integer
    } else if (minimumCapacity > newCapacity) { //is it enough?
        //if doubling wasn't enough, use the actual length computed
        newCapacity = minimumCapacity;
    }
    //copy the old value in the new array
    value = Arrays.copyOf(value, newCapacity); 
}

Arrays.copyOf(char[] original, int newLength) Copies the specified array, truncating or padding with null characters (if necessary) so the copy has the specified length.

In our case, padding, since we're expanding the length.

share|improve this answer
add comment

The source is your friend, Luke!

Here is the source for AbstractStringBuilder

share|improve this answer
    
AbstractStringBuilder being the parent class of StringBuilder –  John B Nov 4 '11 at 15:10
add comment

This doesn't compile.

String S= "orange";
S.append("apple");

if you do

final String S= "orange";
final S2 = S + "apple";

This doesn't create any objects as it is optimised at compile time to two String literals.

StringBuilder s = new StringBuilder("Orange");
s.append("apple");

This creates two objects StringBuilder and the char[] it wraps. If you use

String s2 = s.toString();

This creates two more objects.

If you do

String S= "orange";
S2 = S + "apple";

This is the same as

String S2 = new StringBuilder("orange").append("apple").toString();

which creates 2 + 2 = 4 objects.

share|improve this answer
add comment

String is immutable. Appending a string can only generate a new string.

StringBuilder is mutable. Appending to a StringBuilder is an in-place operation, like adding to an ArrayList.

share|improve this answer
    
Hi Slaks, I know that. I want to know how string builder is doing that operation. –  javaMan Nov 5 '11 at 14:07
add comment

StringBuffer, like StringBuilder allocates an array of char into which it copies the strings you append. It only creates new objects when the number of characters exceeds the size of the array, in which case it reallocates and copies the array.

share|improve this answer
add comment

StringBuilder is holding a buffer of chars in a char[] and converting them to a String when toString is called.

share|improve this answer
add comment
String s = "orange";
s.append("apple");

It is not correct because append method is not available in String:

share|improve this answer
add comment

As others described, StringBuffer is mutable and it is implemented by using a char array. Operations in the StringBuffer are in-place operations.

More INFO can be available from the following link http://www.concentric.net/~ttwang/tech/jfastbuf.htm

It shows simple StringBuffer implementations using a char array.

share|improve this answer
add comment
****String s1="Azad"; ----One object will create in String cons. pool

System.out.println(s1);--output--Azad

s1=s1.concat("Raja");  Two object will create 1-Raja,2-AzadRaja and address of AzadRaja Store in reference s1 and cancel ref.of Azad object 

System.out.println(s1);  --output AzadRaja****
share|improve this answer
    
Your answer is very difficult to read. Does it add any useful information that is not already contained in the accepted answer? –  Duncan Oct 27 '12 at 17:26
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.