programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Jeanne Boyarsky
• Ron McLeod
• Paul Clapham
• Liutauras Vilda
Sheriffs:
• paul wheaton
• Rob Spoor
• Devaka Cooray
Saloon Keepers:
• Stephan van Hulst
• Tim Holloway
• Carey Brown
• Frits Walraven
• Tim Moores
Bartenders:
• Mikalai Zaikin

# Unexpected StringBuilder behaviour (slightly OT)

Ranch Hand
Posts: 91
• Number of slices to send:
Optional 'thank-you' note:
the code
StringBuilder sb = new StringBuilder("abcde");
System.out.println(sb.insert(1, sb));

produces aaaaaabcde

--> neither aabcdebcde nor infinite recursion... neither fish nor fowl

regards

Greenhorn
Posts: 14
• Number of slices to send:
Optional 'thank-you' note:
I think I've worked it out....but I'm not sure how to explain it!!!

I suspect that one of the first things that the insert method does is count how many characters are going to be inserted, which in this case is going to be 5, the initial size of sb. Since the insert method will only try and insert a finite number of characters it will not end up doing an infinite recursion.

Here is how I think it works..

Before the insert sb = abcde

Insert the first character (position 0) from sb into sb at position 1 gives us

sb = aabcde

Insert the second character (position 1) from sb into sb at position 1 gives us

sb = aaabcde

Insert the third character (position 2) from sb into sb at position 1 gives us

sb = aaaabcde

Insert the fourth character (position 3) from sb into sb at position 1 gives us

sb = aaaaabcde

Insert the fifth character (position 4) from sb into sb at position 1 gives us

sb = aaaaaabcde

Which is the answer you got.

Ranch Hand
Posts: 381
• Number of slices to send:
Optional 'thank-you' note:
Correct explanation.
I have tested the argument given by David with a little modification

StringBuilder sb = new StringBuilder("abcde");
System.out.println(sb.insert(2, sb));

The output comes is abababacde,which justifies the above explanation.

Ranch Hand
Posts: 72
• Number of slices to send:
Optional 'thank-you' note:
I have some doubts in the explanation given by David.

-----------------------------------------------------------------------------
Originally written by David :

I suspect that one of the first things that the insert method does is count how many characters are going to be inserted, which in this case is going to be 5, the initial size of sb.
-----------------------------------------------------------------------------

I agree to this line.

-----------------------------------------------------------------------------
Originally written by David :

Since the insert method will only try and insert a finite number of characters it will not end up doing an infinite recursion.
-----------------------------------------------------------------------------

Here I don�t understand why should a recursion come into picture ???

Ideally what I feel is
sb.insert(1, sb));
should mean Insert the value of sb into sb at position 1.
So the answer should be aabcdebcde ( I know that this is not the correct answer )

To justify my above understanding I twisted the given example a bit.

StringBuilder sb = new StringBuilder("abcde");
StringBuilder bc = new StringBuilder("123");
System.out.println(bc.insert(1,sb));

Here the answer comes as I expected 1abcde23 So if there would be any kind of recursion than why that recursion didn�t work in this case ???

Sanjeev Singh
Ranch Hand
Posts: 381
• Number of slices to send:
Optional 'thank-you' note:
Your twisted trick is not the same as the above example here you are trying to insert a completely new stringbuffer.Definately will print what you got.
Internally it is a native call for the Array copy,which is done character to character.It is not like inserting a whole string.
Run the program in your mind with inserting the character one by one.

Ranch Hand
Posts: 35
• Number of slices to send:
Optional 'thank-you' note:
I agree to Vyas. Please explain this explanation given at

The characters of the CharSequence argument are inserted, in order, into this sequence at the indicated offset, moving up any characters originally above that position and increasing the length of this sequence by the length of the argument s.

it says moving up any characters originally above that position

Loveen Jain
Ranch Hand
Posts: 35
• Number of slices to send:
Optional 'thank-you' note:
This explanation was given in the Java API documentation for StringBuilder

David Grindley
Greenhorn
Posts: 14
• Number of slices to send:
Optional 'thank-you' note:
Infinite recursion is actually the wrong term. You could implement the StringBuffer insert method so that it would go into an infinite loop.

Have a look at this bit of code which shows two different ways that you can insert the content of a StringBuffer into itself. One method works as per the initial question. The other method shows how you can code it so that an infinite loop occurs.

Regards
[ November 03, 2006: Message edited by: David Grindley ]

Ranch Hand
Posts: 45
• Number of slices to send:
Optional 'thank-you' note:
Sorry! How the second version gets into infinite loop?

Ranch Hand
Posts: 7729
• Number of slices to send:
Optional 'thank-you' note:
David wrote: "I suspect that one of the first things that the insert method does is count how many characters are going to be inserted"

There is no need to rely on suspicion. The API for StringBuilder explicitly states that StringBuilder's insert(int dstOffset, CharSequence s) method is equivalent to its overloaded version insert(int dstOffset, CharSequence s, int start , int end) where start is 0 and end is s.length().

Saurabh Vyas
Ranch Hand
Posts: 72
• Number of slices to send:
Optional 'thank-you' note:
This is how I try to understand the initial problem again.

sb.insert(1, sb));

so internally insert method will count how many characters are going to be inserted at position 1 in sb.

Now it will run some internal loop (the number of times the loop will iterate depends on the length of the string to be inserted � length is counted initially only � ie only for once during the start the length is decided, so it don�t run into an infinite loop) where it will read one character at a time from sb and will decide the position where it has to be inserted.

Here the string is �abcde�, so insert method will decide that it has to insert 5 characters at position 1 in sb.

So during the first iteration of the internal loop, it selects the first character ( which happens to be �a� from �abcde� ) and will insert it at position 1 in sb. Thus internally now sb gets changed to �aabcde�.

During the second iteration of the internal loop it selects the second character ( which again happens to be �a� from �aabcde� � our new sb value ) from sb and tries to inserts after the first character ie at the second position. Thus internally now sb gets changed to �aaabcde�.

Similarly during the third iteration of the loop, it selects the third character ( which again happens to be �a� as our new sb value is �aaabcde�) and will insert it at the next position ie 3rd position. Thus now our sb gets changed to �aaaabcde�.

Thus during every loop it updates the value of sb and during each iteration it dynamically reads the new character to be inserted at the next position in sb � which always turns out to be �a�. So five �a� gets added at position 1 in sb . Thus our final answer comes out to be �aaaaaabcde� .

Sanjeev Singh
Ranch Hand
Posts: 381
• Number of slices to send:
Optional 'thank-you' note:
Saurabh,

I am afraid you can not apply the same rule on sb.insert(0, sb));
It is giving a output of abcdeabcde.

Can you?

Saurabh Vyas
Ranch Hand
Posts: 72
• Number of slices to send:
Optional 'thank-you' note:
Second version of the example by David runs into infinite loop because during each iteration of for loop it goes and fetches cs.length(), and cs is a reference to sb, while during each iteration the length of sb keeps on changing by value 1 and thus version2 runs into an infinite loop.

Greenhorn
Posts: 21
• Number of slices to send:
Optional 'thank-you' note:
I agree with David - Thanks for your explaination - Running it through manually and you'll see how it works.

Ranch Hand
Posts: 61
• Number of slices to send:
Optional 'thank-you' note:
I agree for above example with david but its only limited for insert method with offset 1 and above and not working for 0 as the code belo shows output as abcdeabcde and the code given by david giving another thing, as all of us expect from the code.

Naveen Zed
Ranch Hand
Posts: 61
• Number of slices to send:
Optional 'thank-you' note:
I agree for above example with david but its only limited for insert method with offset 1 and above and not working for 0 as the code belo shows output as abcdeabcde and the code given by david giving another thing, as all of us expect from the code.
Whats the point I am missing here?

 Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters?