Coming Up for Air

String.format()... You May Be Doing It Wrong

If you’ve been working with Java for very long, you’ve probably had occasion to use String.format() . And, if you’re like me, you may very well have been doing it "wrong". Let’s take a look at what was, for me, common usage, and how, maybe, you should be doing it.

Let’s start by taking a look at a mildly complex — and highly contrived — usage:

String foo = String.format("one %s two %s three %s four %s five %s one again %s",
        "1", "2", "3", "4", "5");
System.out.println(foo);

Other than being beyond ugly, can you spot the problem? Six format specifiers, and five values. It compiles just fine, but blows up at runtime, so that’s no good. There are, of course, other ways to build such a string. StringBuilder comes quickly to mind, but there are times when a use of format() makes more readable code than a series of calls to append() .

String foo2 = new StringBuilder("one ")
    .append("1")
    .append(" two ")
    .append("2")
    .append(" three ")
    .append("3")
    .append(" four ")
    .append("4")
    .append(" five ")
    .append("5")
    .append(" one again ")
    .append("1")
    .toString();

Not really a whole lot prettier, but the point here isn’t finding the prettiest way to write something like this. We’re trying to see how to use String.format() in a safer, more reliable way, so let’s get to it.

get on with it

The key is the "argument index", which you can read more about here. Using the argument index, you can specify which value in the argument list goes with the format specifier in question. Using that, we could rewrite the first example like this:

String foo3 = String.format("one %1$s two %2$s three %3$s four %4$s five %5$s one again %1$s",
        "1", "2", "3", "4", "5");
System.out.println(foo3);

This doesn’t solve the missing argument issue, but it does allow us to avoid repeating values. It’s not super obvious in this example, so let’s try an uglier one, one in which a particular value needs to be repeated many, many times:

String foo4 = String.format("one %1$s two %1$s three %1$s four %1$s five %1$s", "1");
System.out.println(foo4);

Six format specifiers, one value. Pretty fancy, eh?

So, if you find yourself needing to build a complicated string, especially with a large number of repeating values, argument indices are your friend. And don’t be too hard on yourself if this is new to you. I just learned it about too, so you’re in good…​ well…​ you have company. :)

tags: Java

Quotes

Sample quote

Quote source