33

What should be used for a basic string concatenation operation ?

String randomString = "hello " + userName + " how are you" ?

or

String randomString = String.format("hello %s how are you ?",userName);

I feel String.format() gives a better idea of output string. But what are actually pro and cons in using any of one ?

Is there anything in terms of performance or orphan entries in string literal pool.

Edit : I am talking about multiple parameters in string, not just one. Around 5 +.

Bonus Question : Please also share your view on which one should actually use ? any one of these or 3rd one... !! ?

Priyank Doshi
  • 12,895
  • 18
  • 59
  • 82
  • 3
    Might be a duplicate of http://stackoverflow.com/q/925423/1135954 – mtk Dec 11 '12 at 07:27
  • @mtk An interesting point from the answer to that question is the idea of localization. Using string internationalization, you can switch out the first argument to `String.format` with one that has different parameter ordering or phrasing without having to recompile. This is a *huge* strength of `String.format`. – Brian Dec 11 '12 at 07:42

9 Answers9

32

If you are looking for performance only I believe that using StringBuilder/StringBuffer is the most efficient way to build strings. Even if the Java compiler is smart enough to translate most of String concatenations to StringBuilder equivalent.

If you are looking for readability the String.format thing is the much clearer I think, and this is what I use also unless I need to rely on high performance.

So if your main concern is not performance, meaning this code is not in a path that is called a lot, you may prefer to use String.format as it gives a better idea of the resulting String (like you said).

Besides, using String.format lets you use the format thing, which means you can use it for padding Strings, formatting numbers, dates, and so on, which would make the code even worse if using simple concatenation.

Edit for Chuu:

Using JAD, you can see that the following code:

public class Test {
    public static void main(String[] args) {
        String str = "a" + "b" + "c";
        String str2 = "foo" + str + "bar" + str;
        System.out.println(str2);
    }
}

when decompiled will look like:

public class Test {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new StringBuilder("foo").append(str).append("bar").append(str).toString();
        System.out.println(str2);
    }
}

Proof of that can also be found using the javap utility that will show you the Java bytecode under a .class file:

public static void main(java.lang.String[] args);
    0  ldc <String "abc"> [16]
    2  astore_1 [str]
    3  new java.lang.StringBuilder [18]
    6  dup
    7  ldc <String "foo"> [20]
    9  invokespecial java.lang.StringBuilder(java.lang.String) [22]
   12  aload_1 [str]
   13  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   16  ldc <String "bar"> [29]
   18  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   21  aload_1 [str]
   22  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   25  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [31]
   28  astore_2 [str2]
   29  getstatic java.lang.System.out : java.io.PrintStream [35]
   32  aload_2 [str2]
   33  invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]
   36  return
Alex
  • 25,147
  • 6
  • 59
  • 55
  • I don't know the specific of Android's java implementation, but in most dynamic languages the '+' operator will always be the fastest way to concat strings. This is because most jitters will translate this into computing the size of the resultant string, do one single memory allocation, and then copy everything into the memory it allocated. String.format and StringBuffer both require multiple dynamic allocation and/or create temporary objects to be collected. – Chuu Dec 11 '12 at 14:57
  • 1
    The Java compiler will translate `"a" + "b" + "c"` to `"abc"` automatically, but if it involves a variable, it uses `StringBuilder` when possible, so `String str1 = "a"; String str2 = "a" + str1;` will be translated to `String str2 = new StringBuilder("a").append(str1)).toString();`. This behavior can be verified using a Java decompiler like JAD. – Alex Dec 11 '12 at 15:21
  • 1
    @Chuu see also the edit above. – Alex Dec 11 '12 at 15:31
  • @Alex: Chuu's claim seem to be about JIT:ers. They work with optimisations during runtime and load time and this will not be visible in the class files. – Lii Jan 29 '15 at 13:18
  • @Alex did you mean `String str = "abc";` instead of `String str = "ac";` in the decompiled file? – Vikas Prasad Jul 29 '17 at 06:12
  • @VikasPrasad of course, nice catch :) – Alex Aug 13 '17 at 12:52
8

What should be used for a basic string concatenation operation ?

The examples you provide serves different purposes. + is overloaded to concat Strings but String.format is used to format strings, as name specifies.

Concatenating strings together is not it's primary job.

So, if the requirement is just to concatenate use + or concat method.

These links will be useful:

Should I use Java's String.format() if performance is important?

Is it better practice to use String.format over string Concatenation in Java?

Tarun
  • 3,456
  • 10
  • 48
  • 82
Azodious
  • 13,752
  • 1
  • 36
  • 71
7

Try this

    long t0 = System.currentTimeMillis();
        String userName = "test";
        for (int i = 0; i < 1000000; i++) {
            String randomString = "hello " + userName + " how are you?";
//          String randomString = String.format("hello %s how are you ?",userName);
        }
        System.out.println(System.currentTimeMillis() - t0);

you will be surprised to know that concatination is 10 times faster that String.format. But format can do a lot of extremely useful things with numbers, dates, etc. See java.util.Formatter API, which is actually used by String.format, for details.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • 2
    +1 for performance testing – DerMike Dec 11 '12 at 11:26
  • Since the compiler is concatenation using + operator to StringBuilder implementation, it will be faster. But yes! String.format is a lot slower as far as concatenation is concerned. – arunken Jan 03 '22 at 05:57
3

In my opinion, use + operator.

If performance is a concern you should be using StringBuilder and as Alex pointed out in his comment above, the Java compiler will convert:

String str2 = "a" + str1;

to: String str2 = new StringBuilder("a").append(str1)).toString();

In addition to this you can avoid runtime exceptions by using the + operator. Instead you'll get syntax errors that you can catch at compile time. For example:

    String var = "huge success.";

    System.out.print( "I'm making a note here: " + var );
    //System.out.print( "Printing: " + ); Syntax error!

    System.out.print( String.format( "I'm making a note here: '%s'", var ) );
    System.out.print( String.format( "I'm making a note here: '%s'" ) ); // runtime exception!
    System.out.print( String.format( "I'm making a note here: '%d'", var ) ); // runtime exception!

Readability comes down to personal preference. However I will say that the String.format syntax is basically from C++ and most language created since then have embraced the + operator for readability reasons.

rhinoinrepose
  • 2,110
  • 2
  • 19
  • 26
2

My two cents: always use String.format()

Internationalisation is a much bigger concern than style or performance in this situation. For that reason I would always use String.format()

English text: "Hello " + userName + " how are you?"

Translation into Jedi: userName + "you are how? Hello!"

If the strings are concatenated, changing word order can be difficult if not impossible for the translator. This problem becomes increasingly worse as there are more pieces to the string and more placeholders.

njr101
  • 9,499
  • 7
  • 39
  • 56
1

Personally I'd prefer to use formatting as it looks better and I can't imagine it impacting performance heavily.

Duane
  • 1,980
  • 4
  • 17
  • 27
1

Most people recommending using StringBuffer are living in the past. The current best practice is to use a StringBuilder. But this might change, so why not let the compiler do that for you? When you just use the "+" the compiler will choose the besst current implementation, which can even combine static strings ("foo" + "bar" will become a single "foobar").

The onle place where I would explicitly allocate a StringBuilder is in Loops (where it is created before the loop and used within).

Check the generated Bytecode if you are in doubt what happens.

So when to use format? I would use format when the actual formatting is complicated. But you are talking about simple concatenation right now.

Fabian Lange
  • 1,786
  • 1
  • 14
  • 18
1

I think String.Format is more efficient, because it have following advantages,

  1. Improved readability
  2. Better translatable
  3. You can use format providers and simple format indicators (like fixed width) right in the format string.
  4. You can do some powerful things by putting format strings in configuration files.
  5. String.Format() is often faster, as it uses a StringBuilder and an efficient state machine behind the scenes, whereas string concatenation in .Net is relatively slow. This is especially true as the size of the string and number of substituted values increases.

Thanks.

Chetan S
  • 935
  • 1
  • 11
  • 21
0

My main concern with String.format is that it's a locale-specific operation and you may end up with unpredicted results if your code is run in a different locale.

I'd like to have a non-locale alternative to it as its compact syntax is really nice.

Agustí Sánchez
  • 10,455
  • 2
  • 34
  • 25