Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String concatenation: concat() vs "+" operator

Assuming String a and b:

a += b a = a.concat(b) 

Under the hood, are they the same thing?

Here is concat decompiled as reference. I'd like to be able to decompile the + operator as well to see what that does.

public String concat(String s) {      int i = s.length();     if (i == 0) {         return this;     }     else {         char ac[] = new char[count + i];         getChars(0, count, ac, 0);         s.getChars(0, i, ac, count);         return new String(0, count + i, ac);     } } 
like image 338
shsteimer Avatar asked Sep 06 '08 16:09

shsteimer


People also ask

What is the difference between the concat () method and join () method of Array object?

Join allows seperator as explicit parameter and string. Concat doesn't have such parameter. Hello @BjrnUitenbroek, Concatenation adds two strings and join separates the strings from Array.

Is concatenation is a string operator?

Concatenation operators join multiple strings into a single string. There are two concatenation operators, + and & . Both carry out the basic concatenation operation, as the following example shows.

Which operator is used for string concatenation?

Operator + is used to concatenate strings, Example String s = “i ” + “like ” + “java”; String s contains “I like java”.


1 Answers

No, not quite.

Firstly, there's a slight difference in semantics. If a is null, then a.concat(b) throws a NullPointerException but a+=b will treat the original value of a as if it were null. Furthermore, the concat() method only accepts String values while the + operator will silently convert the argument to a String (using the toString() method for objects). So the concat() method is more strict in what it accepts.

To look under the hood, write a simple class with a += b;

public class Concat {     String cat(String a, String b) {         a += b;         return a;     } } 

Now disassemble with javap -c (included in the Sun JDK). You should see a listing including:

java.lang.String cat(java.lang.String, java.lang.String);   Code:    0:   new     #2; //class java/lang/StringBuilder    3:   dup    4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V    7:   aload_1    8:   invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;    11:  aload_2    12:  invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;    15:  invokevirtual   #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/    String;    18:  astore_1    19:  aload_1    20:  areturn 

So, a += b is the equivalent of

a = new StringBuilder()     .append(a)     .append(b)     .toString(); 

The concat method should be faster. However, with more strings the StringBuilder method wins, at least in terms of performance.

The source code of String and StringBuilder (and its package-private base class) is available in src.zip of the Sun JDK. You can see that you are building up a char array (resizing as necessary) and then throwing it away when you create the final String. In practice memory allocation is surprisingly fast.

Update: As Pawel Adamski notes, performance has changed in more recent HotSpot. javac still produces exactly the same code, but the bytecode compiler cheats. Simple testing entirely fails because the entire body of code is thrown away. Summing System.identityHashCode (not String.hashCode) shows the StringBuffer code has a slight advantage. Subject to change when the next update is released, or if you use a different JVM. From @lukaseder, a list of HotSpot JVM intrinsics.

like image 98
Tom Hawtin - tackline Avatar answered Oct 16 '22 18:10

Tom Hawtin - tackline