By dave | March 22, 2015

Over the years there have been no shortage of ways to format a string in java. What with the + operator, StringBuffer, StringBuilder, String.format(..) and various specialised formatters for numbers and dates we sometimes feel a little spoilt for choice. But how do they all work and what are their advantanges / disadvantages?

 

StringBuffer - a hang up from times gone by!

StringBuffer is a synchronized object! Yes, everything you do with it will cause synchronization. This is for historic reasons, unless you actually want this side effect use StringBuilder which has the same methods without the overhead.

StringBuilder - an easy way to concatenate data.

This object provides a simple way to concatenate various types. See the example below that uses StringBuilder to concatenate a String, char and a String:

public class Formatting
{
    public static void main(String[] args)
    {
        final int DEFAULT_SIZE = 100;
        StringBuilder sb = new StringBuilder(DEFAULT_SIZE);
        sb.append("Hello");
        sb.append(' ');
        sb.append("World");

        System.out.println(sb.toString());
    }
}

Note that when I construct the object I pass in the desired capacity, this is because the default size of a StringBuilder is 16 characters, so to grow to 256 characters would take several re-allocations.

Whats wrong with adding strings together anyway?

For tne vast majority of code, nothing whatsoever, as long as its readable. Unless you are in a critical section of code, there probably little wrong with just adding strings together using the + and += operator. For example, the slight overhead of doing this would need to happen very frequently to have significant impact. In addition, I believe that if used carefully it does not make the code less readable. For some time java compilers have optimised this out into a series of calls to StringBuilder. Just note the above problem, with the default size of StringBuilder as this applies here to.

Formatting with String.format(..)

java.util.Formatter and String.format(..) were introduced in Java 1.5. These provide functionality similar to printf in C++ (actually a bit more like sprintf). We will always use String.format in this example. For those familiar with printf, you can skip the next paragraph.

Using printf for formatting in C made some tasks very simple, hence why its made a comeback several years later in Java. Many of the runtime disadvantages associated with printf in C do not have the same consequences in Java. For example parameter mismatch was a serious problem in C, but in Java can be handled via an exception. However, one disadvantage of using this is that the String must be parsed each time the method is called.

Format works by parsing the format string (first parameter), and for each escape (%) found, it replaces the escape with the next parameter. If there are too few parameters an exception is thrown. Each escape is made up of the % character followed by type information (and optionally a formatting specification). For simple escapes, 's' is a String, 'd' is an integer and 'f' is floating point. Without further delay, lets take a look:

public class Formatting
{
    public static void main(String[] args)
    {
        int iVal = 10;
        long lVal = 30;
        double dVal = 3.5;

        // simple example just print an integer, double and long.
        String simpleFmt = String.format("Values: %d %f %d", iVal, dVal, lVal);
        System.out.println(simpleFmt);

        // Complex formatting example using same variables as above
        // %04d - integer with 4 places zero padded.
        // %.2f - floating point to two decimal places after point.
        // %9d - integer padded to 9 places not zero padded.
        String specificFmt = String.format("Values: %04d %.2f %9d", iVal, dVal, lVal);
        System.out.println(specificFmt);
    }
}

    Output:
    Values: 10 3.500000 30
    Values: 0010 3.50        30
 

Something to note, if you are using this in a tight loop is that the default construction for String.format and the underlying formatter class allocates a buffer of only 16 characters. For most casual uses this is fine.

Notice that the line of first output does not contain any padding, and the floating point value is to 6 places of precision; these are the defaults when using format. However, the second line is somewhat different, notice the zero padding and space padding of the first and last item. Also note that the floating point value is to a lesser precision.

Other pages within this category

comments powered by Disqus

We use cookies to analyse traffic and to personalise content. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Please see our privacy policy should you need more information or wish to adjust your settings.