It's certainly possible to do this without concatenation if you want to. Although it's probably not very worthwhile.
It partly depends on where you're going to display the result. If it's on the web or the console, then you can write the result directly to an output stream.
So for example, if your template was something like "the %001 jumped out of the %002" you could:
1) scan the string to find where the variables are.
2) break the string into a list of components "the","jumped out of the", in this case
3) loop through the elements of your list and the results and dump them to output with something like this:
PrintStream = //get output from somewhere
for(int i = 0; i < pieces.size()-1 ; i++){
ps.print(peices.get(i));
ps.print(answers.get(i));
}
ps.print(pieces.get(pieces.size()-1));//last one
Now. I don't know if you would call that 'elegant' or not. It would probably be kind of fast. Like I said, maybe appropriate if this was a web service and it became super popular, etc.
If this is a GUI app, you could write code to draw the strings separately, but that would probably take more time then concatenation.
but one thing you could do is use a ByteArrayOutputStream and pre-allocate enough space so that it could contain the filled out madlib without making additional allocations. That would be pretty quick as well.