Possibility and Probability

A Python programmer with a personality thinking about space exploration

26 April 2006

java.lang.StringBuffer Blues

by Nick

Although we live in the future, and in the future everyone uses XML, there are still times when you need to interface with something that uses fixed position strings to relay information. This happened to me the other day at work and I thought I would share somethings I learned. My first thought was to find something that would allow me to insert characters into a String at a specified point. Strings are immutable, so they aren’t ideal. The StringBuffer class is designed to be manipluated, so it seemed like the perfect fit. Looking through the API docs I saw that it had useful sounding methods like “insert()”. Boy was I in for a shock. When you build a StringBuffer, you can specify the length of it. Since I’m going to be building a String of a specific length it seemed like a snap, just build a StringBuffer of that length. But when I tried to use that StringBuffer, I kept getting index exceptions. It turns out that when you pass in a number to the constructor it allocates the space (plus 16), but doesn’t put anything in it. For some reason when I started putting strings into the StringBuffer (via the insert() method) I would eventually get the error. Stepping through the debugger showed that the buffer was allocated, but something just didn’t seem right. When ever I would try to print out the StringBuffer it never seemed right, like it was stopping in the middle for some reason. So, as a quick test I used the constructor that allows you to pass in a String, and I passed in a String of spaces that was the right length. Lo-and-behold everything started working correctly. That was slightly annoying to me because from everything I read it seemed like I shouldn’t have to pass in a string of spaces in order for this to work.

As as side note, I really really really don’t like variables that are just strings of spaces that have to be a certain length. It is almost impossible to count out the spaces, plus if someone ever accidentally removes/adds a space it is a pain to debug. It is much better to specify a length and then build the string of spaces at runtime (if it simply must be done).

So, once I had that figured out I thought it was going to be clear sailing. Ugly, but clear. Wrong again. It turns out the insert() isn’t the best choice for inserting things. Insert doesn’t overwrite anything in the buffer (which is cool, but now that I have my crazy String of spaces I would prefer it to overwrite, but hey this ain’t Burger King so I’m not gonna get it my way). Instead it simply inserts. Which eventually causes the index exception. D’oh!!!! It turns out that replace() is a much better choice. However it requires a lot of parameter to be passed in, and soon the code I was writing looked like a war zone. So at this point I had to create a new Class to wrap up all of the ugliness and still keep it useful. It turns out this was a pretty good move to make, because a little while later I discovered that there were times were I would want to insert something, but have it justified one way or the other. Simply adding a method to my new class allowed me to keep the code nice a clean, and debuggable (because all of that logic was contained in once place). Score one for Object-Orientation. Anyways, the moral of this story is that the Java API is pretty good, but is lacking in some areas (don’t get me started on the nightmare that is the StringTokenizer class). A well crafted wrapper class can help create the functionality that might be missing and also allow you the chance to keep your main business logic code looking clean. Plus the benefit of having that kind of code (the kind that is subject to changing requirements) in one place for debugging and maintenance can not be understated.

tags: