Java StringBuilder

Posted by & filed under , , , .

This is something that I have seen quite a few times while looking online at other people’s code so I thought I’d write about it quickly — preach the world and all that 🙂 I’m referring here to the JDK class StringBuilder, however, those of you who know your JDK classes would surely have figured out by now that the same applies to StringBuffer (though why would you still use it?). It appears a lot of people out there still use a 2-line approach to initialise a StringBuilder — probably due to some old habbits that say you need to separate your initialisation of the variable from using it (a whole discussion around this to be had surely as a general rule but I’m not getting into that, I’m strictly referring here to our StringBuilder class):

StringBuilder buffer = new StringBuilder();
buffer.append( "Enter function checkPassword, user still not validated" );

While it’s probably true that some compilers can optimise that, it’s just as true that some compilers might not! And also, it’s true that you are forcing here the following operations:

  1. Object is initialised and the internal buffer is created with a initial (default) length of 16 characters!
  2. Having initialised the object we then call a method on this object (append) and pass it a parameter
  3. Since our parameter length is greater than 16 characters, the buffer size needs to be expanded, content copied over then finally our parameter is appended at the end

So not only this code will run slower, but it will generate a memory block marked straight away for garbage collection — and in a high throughput system your garbage collector will have to kick in a lot of times to reclaim that memory thus slowing your app down.

Now how about the following approach:

StringBuilder buffer = new StringBuilder( "Enter function checkPassword, user still not validated" );

Would you believe that the memory allocation of the buffer is done upfront to match the size of our parameter, and there is no second call to append! So faster execution and no extra memory!

The other thing that I see a lot is not a mistake, it’s more of a question of style I guess, but I’m guessing again there are others not knowing this so it’s worth signalling it:

StringBuilder s = new StringBuilder( "message1" );
...
s.append( "message2" );
s.append( "message3" );
s.append( variable1 );
s.append( variable2 );

There is nothing wrong with the above — but you are taking a few lines of code and it makes it a bit more difficult (I found) scrolling through the code. With StringBuilder you can chain calls to append because that returns the StringBuilder object itself! So you can write the above as follows:

StringBuilder s = new StringBuilder( "message1" );
...
s.append( "message2" ).append( "message3" ).append( variable1 ).append( variable2 );

or event more concise:

StringBuilder s = new StringBuilder( "message1" ).append( "message2" ).append( "message3" ).append( variable1 ).append( variable2 );

Last but not least, I’ve seen this a few times, no doubt the person was junior, but it’s worth pointing out if you’re using a StringBuilder you might just as well make use of it and not rely on the old String concatenation:

StringBuilder s = new StringBuilder();
...
s.append( "Error opening file " + fileName + ", error was " + errorMessage );

Please, please, please use the right way and write your code like this:

StringBuilder s = new StringBuilder();
...
s.append( "Error opening file " ).append( fileName ).append( ", error was " ).append( errorMessage );