This discussion is archived
9 Replies Latest reply: Jul 28, 2009 5:17 AM by 791266 RSS

Bug in StringBuilder and its setLength ?

807588 Newbie
Currently Being Moderated
Hi

I hope this is the right sub-forum for this type of post.

When using StringBuilder and the setLength method, then some strange things happen. Before reporting this as a bug I would like to hear you if you think I have misread the API for StringBuilder and particular setLength.

An example:
public class StringBuilderTest
{

    /**
     * Test method for {@link java.lang.AbstractStringBuilder#setLength(int)}.
     */
    public final void testSetLength ()
    {
        StringBuilder sb1 = new StringBuilder ();
        StringBuilder sb2 = new StringBuilder ();
        StringBuilder sb3 = new StringBuilder ();
        
        String messageString = "This is a test of:\nStringBuilder\nToday we test setLength!\n";
        
        System.out.println ("Test string:" + messageString);
        
        sb1.append (messageString);
        
        sb2.setLength (messageString.length ());
        sb2.append (messageString);
        
        sb3.setLength (messageString.length () + /* some arbitrary number - say */ 20);
        sb3.append (messageString);

        System.out.println ("messageString:" + messageString);
        System.out.println ("sb1:" + sb1);
        System.out.println ("sb2:" + sb2);
        System.out.println ("sb3:" + sb3);
        
        if (messageString.equals (sb1.toString ()))
        {
            System.out.println ("Success! messageString and sb1.toString() are equal!");
        }
        else
        {
            System.out.println ("FAILED! messageString and sb1.toString() where NOT equal!");
        }
        
        if (messageString.equals (sb2.toString ()))
        {
            System.out.println ("Success! messageString and sb2.toString() are equal!");
        }
        else
        {
            System.out.println ("FAILED! messageString and sb2.toString() where NOT equal!");
        }
        
        if (messageString.equals (sb3.toString ()))
        {
            System.out.println ("Success! messageString and sb3.toString() are equal!");
        }
        else
        {
            System.out.println ("FAILED! messageString and sb3.toString() where NOT equal!");
        }
    }

    public static void main (String[] args)
    {
        StringBuilderTest sBT = new StringBuilderTest ();
        sBT.testSetLength ();
    }
}
I was using java 6 (1.6.0.14).

Below the output when using Eclipse v3.3.1.1 and its console:
Test string:This is a test of:
StringBuilder
Today we test setLength!

messageString:This is a test of:
StringBuilder
Today we test setLength!

sb1:This is a test of:
StringBuilder
Today we test setLength!

sb2:
StringBuilder
Today we test setLength!

sb3:
StringBuilder
Today we test setLength!

Success! messageString and sb1.toString() are equal!
FAILED! messageString and sb2.toString() where NOT equal!
FAILED! messageString and sb3.toString() where NOT equal!
, remark: I had to copy&paste in parts after 'sb2:' and 'sb3:' from the console.

Now, If I compile and run from the console instead of using eclipse the messageString and the string buffers 2 and 3 are still not equal:
Test string:This is a test of:
StringBuilder
Today we test setLength!

messageString:This is a test of:
StringBuilder
Today we test setLength!

sb1:This is a test of:
StringBuilder
Today we test setLength!

sb2:This is a test of:
StringBuilder
Today we test setLength!

sb3:This is a test of:
StringBuilder
Today we test setLength!

Success! messageString and sb1.toString() are equal!
FAILED! messageString and sb2.toString() where NOT equal!
FAILED! messageString and sb3.toString() where NOT equal!
, however I get the strings printed out.

I guess the problem is related to the handling of new lines perhaps, but how this relates to setLength I have no clue about.
(Sorry, I know I have a typo: I have written 'where' where I wanted to write 'were' in the output lines above.)

Tell me please where did I make a mistake? :-)

Edited by: a_l on Jul 28, 2009 4:08 AM
  • 1. This Thread is now moved
    791266 Explorer
    Currently Being Moderated
    Note: This thread was originally posted in the [Conventional & Interruptable IO|http://forums.sun.com/forum.jspa?forumID=535] forum, but moved to this forum for closer topic alignment.
  • 2. Re: Bug in StringBuilder and its setLength ?
    791266 Explorer
    Currently Being Moderated
    The string builder contains non printable characters after you call setLength. This illustrates your problem:
         StringBuilder sb2 = new StringBuilder();
         sb2.setLength (messageString.length ());
            sb2.append (messageString);          
            sb2.insert(0, '*');
            sb2.append('*');
            System.out.println(sb2.toString());
    I don't know why you call setLength, and then append data. Why are you calling setLength?
  • 3. Re: Bug in StringBuilder and its setLength ?
    807588 Newbie
    Currently Being Moderated
    The reason calling setLength prior to appending was because I knew the length of the entire content prior to appending. So if I was going to append more strings it would be more feasible to set the length once instead of letting StringBuilder steadily increase the size over time. It was while experimenting I stumbled over this phenomenon.

    But I guess I misunderstood how setLength actutally works - since it appends a lot of '\0' (null) and so instead I should have called ensureCapacity () which I first thought was setLength - perhaps a warning when using setLength should be stated in the javadoc of StringBuilder?

    So I guess it is by design that StringBuilder does not remove one or more '\0' when appending to a StringBuilder, right?

    Thank you very much for your quick answer!

    PS What I should have done to begin with - which I did this time was in Linux to use: 'hexdump -C' to observe the output.

    Edited by: a_l on Jul 28, 2009 4:41 AM

    Edited by: a_l on Jul 28, 2009 4:43 AM
  • 4. Re: Bug in StringBuilder and its setLength ?
    791266 Explorer
    Currently Being Moderated
    So I guess it is by design that StringBuilder does not remove one or more '\0' when appending to a StringBuilder, right?
    Correct, that's why it's called append :)
  • 5. Re: Bug in StringBuilder and its setLength ?
    807588 Newbie
    Currently Being Moderated
    Okay :) At least I hope other people see this thread before they give up :)

    I was simply not used to this behaviour regarding '\0' when appending to some string.
    I see you are a moderator - Do you have rights/influence to add e.g. a warning to the javadoc of StringBuilder so people get a warning when reading about using setLength and/or afterwards appending?
    I guess I am not the only one able to make this sort of mistake.

    Thank you once again!

    Edited by: a_l on Jul 28, 2009 4:58 AM
  • 6. Re: Bug in StringBuilder and its setLength ?
    masijade Explorer
    Currently Being Moderated
    It doesn't need one. Here from the API
    Sets the length of the character sequence. The sequence is changed to a new character sequence whose length is specified by the argument. For every nonnegative index k less than newLength, the character at index k in the new character sequence is the same as the character at index k in the old sequence if k is less than the length of the old character sequence; otherwise, it is the null character '\u0000'. In other words, if the newLength argument is less than the current length, the length is changed to the specified length.
    See, you are setting the length of the CharacterSequence (and it specifically mentions null for those indexes that are beyond the end of the "current" length), and not the capacity of the buffer/builder. And, when you "append" to a CharSequence you append to it, you don't evaluate backwards from the end of String until you find the first printable character and append from there.
  • 7. Re: Bug in StringBuilder and its setLength ?
    791266 Explorer
    Currently Being Moderated
    a_l wrote:
    Okay :) At least I hope other people see this thread before they give up :)

    I was simply not used to this behaviour regarding '\0' when appending to some string.
    I see you are a moderator - Do you have rights/influence to add e.g. a warning to the javadoc of StringBuilder so people get a warning when reading about using setLength and/or afterwards appending?
    I guess I am not the only one able to make this sort of mistake.

    Thank you once again!
    No, I can't influence them, and as the previous poster said, it is already documentet, and I've been posting on these forums for many years, and I can't recall that I've seen this question before.
  • 8. Re: Bug in StringBuilder and its setLength ?
    807588 Newbie
    Currently Being Moderated
    Thank you - yes, I see the lines you pointed out should be understood the way you describe it and not how I initially understood it.

    But yes, I simply had normal concatenation in mind and not appending to the absolute sequence it is. Well, lets close this thread :-) And thanks once again!
  • 9. Re: Bug in StringBuilder and its setLength ?
    807588 Newbie
    Currently Being Moderated
    Even with concatenation the result would be the same. 0x0 is not an end-of-string marker in Java.