This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java String concatenation
Sources tell us that concat is implemented as follows:
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
Does + implementation differ when it comes to Strings? How? Is there a performance difference between + and concat. When should one be chosen over another?
This is a test I just made:
I created a class with those 3 instructions:
String s1 = "foo";
String s2 = "bar";
String s3 = s1 + s2;
Then I took the generated .class file and I decompiled using JAD decompiler.
This is how the code show up in the regenerated source:
String s = "foo";
String s1 = "bar";
String s2 = (new StringBuilder()).append(s).append(s1).toString();
So: this is the difference between + and concat.
I guess concat() is always better than StringBuilder, because it requires less objects to be created. You may chose StringBuilder if you want to append string repeatedly in a loop; in this case concat may create a new String each time, while StringBuilder may just expand the internal buffer. But, if StringBuilder is best in this last scenario, we can say that still concat() is better than +, in loops.
Related
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 4 years ago.
The question is simple, what is better for avoiding of non-appropriated memory using? For example, let's say that we've a String s = "Test" and we'd like to add 1 to it so it becomes Test1. We all know that s gets a memory location and if we use StringBuilder, Test1 will get a new memory address or it'll remain at s's place, and what if we use concat?
One line concatenations are optimized and converted to StringBuilder under the hood. Memory wise is the same thing, but the manual concatenation is more concise.
// the two declarations are basically the same
// JVM will optimize this to StringBuilder
String test = "test";
test += "test";
StringBuilder test = new StringBuilder();
test.append("test");
On the other hand, if you don't do trivial concatenations, you will be better off with StringBuilder.
// this is worse, JVM won't be able to optimize
String test = "";
for(int i = 0; i < 100; i ++) {
test += "test";
}
// this is better
StringBuilder builder = new StringBuilder();
for(int i = 0; i < 100; i ++) {
builder.append("test");
}
This question already has answers here:
String Constant Pool
(5 answers)
Closed 7 years ago.
In this example I thought that the result was true. I thought that the variable stored in the string pool.
The answer was: returns false because the two String objects are not the same in memory. One comes directly from the string pool and the other comes from building using String operations.
String a = "";
a += 2;
a += 'c';
a += false;
if ( a == "2cfalse") System.out.println("==");
I do not understand where the variable a was stored
Okay, so two responses to this. First, the ethically correct one, do never test strings with ==, always use .equals() or .equalsIgnoreCase().
Secondly, it's true that indeed, "a" == "a" because the strings are stored in, as you call it, the same pool. The problem here is that you append to it. Appending to a string causes it to become a different string, which is not stored in the string pool. The string pool is only generated on-compile, and as the second string is calculated on runtime, it won't match the one generated on-compile.
Imagine a string-pool to work like this:
a = "test";
b = "te";
c = "st";
d = "test";
The compiler translates this into
sp1 = "test";
sp2 = "te";
sp3 = "st";
a = sp1;
b = sp2;
c = sp3;
d = sp1;
Now == will check if two variables refer to the same sp. If you run b + c java will not go back and check if any of the sp's is the same as that. It only does that on compile.
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 7 years ago.
I am concatenating a String in a loop but it takes ages, why is that?
for (String object : jsonData) {
counter++;
finalJsonDataStr += object;
}
Variable object is a piece of JSON, up to 70 chars and the loop goes approx 50k times.
I understand some people advice StringBuffer or StringBuilder but this link says, it has no performance improvements: StringBuilder vs String concatenation in toString() in Java
Use a String Builder to append to strings.
When you concatenate, Java is actually creating a new String with the results of the concatenation.
Do it multiple times and you are creating gazillion of strings for nothing.
Try:
StringBuilder sb = new StringBuilder();
for (String object : jsonData) {
counter++;
sb.append(object.toString()); //this does the concatenation internally
//but is very efficient
}
finalJsonDataStr = sb.toString(); //this gives you back the whole string
Remark:
When you do stuff like
myString = "hello " + someStringVariable + " World!" + " My name is " + name;
The compiler is smart enough to replace all that with a single StringBuilder, like:
myString = new StringBuilder("hello ")
.append(someStringVariable)
.append(" World!")
.append(" My name is ")
.append(name).toString();
But for some reason I don't know, it doesn't do it when the concatenation happens inside a loop.
You should use a StringBuffer or a StringBuilder.
When you add Strings with plus, a StringBuilder is created, strings are concatenated and a new String is return with toString() method of the StringBuilder. So image this object creation and string manipulation 50k times. It's much better if you instantiate only one StringBuilder yourself and just append strings...
This answer could be of use to you: concatenation operator (+) vs concat()
Before going to the actual problem, see how internal concatenation works.
String testString ="str"+"ingcon"+"catenation";
If we print the above declared String to console and see, the result is stringconcatenation.Which is correct and the + works fine. Here is out actual question, how does that + symbol did the magic ? ? Is it not a normal mathematical addition of Strings. The below code snippet shows how that code with + actually converts.
StringBuilder compilerGeneratedBuilder = new StringBuilder();
compilerGeneratedBuilder.append("str");
compilerGeneratedBuilder.append("ingcon");
compilerGeneratedBuilder.append("catenation");
String finalString = compilerGeneratedBuilder.toString();
More .....
50K times loop is a descent performance blocker to consider.
In such cases use StringBuilder with append method. Cause concat (+) create a new object every time a new String Builder object. That leads to 50k objects creations.
With single StringBuilder and append method, you can save the time of Objection creation as well as the memory too.
This question already has answers here:
What is the difference between strings allocated using new operator & without new operator in java J2ME?
(5 answers)
Closed 8 years ago.
With new operator String create the string in heap and put a copy in string const pool so the result of hashcode is same in below case;
String s1 = new String("Test");
String s2 = new String("Test");
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
But without using new operator its still giving the same hashcode
String s1 = new String("Test");
String s2 = "Test";
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
Then what is the differnce between above two notation of string creation although they are referening to same string in string const. pool
Based on Effective java.
It is often appropriate to reuse a single object instead of creating a
new function- ally equivalent object each time it is needed. Reuse can
be both faster and more stylish. An object can always be reused if it
is immutable. As an extreme example of what not to do,
consider this statement:
String s = new String("stringette"); // DON'T
DO THIS!
The statement creates a new String instance each time it is
executed, and none of those object creations is necessary. The
argument to the String construc- tor ( "stringette" ) is itself a
String instance, functionally identical to all of the objects created
by the constructor. If this usage occurs in a loop or in a frequently
invoked method, millions of String instances can be created
needlessly.
The improved version is simply the following:
String s = "stringette";
This version uses a single String instance, rather than creating a new
one each time it is executed. Furthermore, it is guaranteed that the
object will be reused by any other code running in the same virtual
machine that happens to con- tain the same string literal
therefore creating unnecessary new Object of String or any other Objects are expensive.
From docs and Java.lang.String class, Internal Implementation of hashCode()
/**
* Returns a hash code for this string. The hash code for a
* String object is computed as
*
* s[0]*31^(n-1) + s1*31^(n-2) + ... + s[n-1]
*
* using int arithmetic, where s[i] is the
* ith character of the string, n is the length of
* the string, and ^ indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* #return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
More about String hashcode here
Both expression gives you String object, but there is difference between them. When you create String object using new() operator, it always create a new object in heap memory. On the other hand, if you create object using String literal syntax e.g. String s2 = "Test"; it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists. Otherwise it will create a new string object and put in string pool for future re-use.
for further reading see:here
String str = new String("String");
always create a new object on the heap.
Here creates a new String having for value the value of the constant "String" and assignates its reference to the variable str.
String str = "String";
uses the String pool
Here assignates the reference associated to the constant "String" to the variable str
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 6 years ago.
What is the benefit and trade-off of using a string builder over pure string concatenation?
new StringBuilder(32).append(str1)
.append(" test: ")
.append(val)
.append(" is changed")
.toString();
vs say
str1 + " test: " + val + " is changed".
str1 is a random 10 character string.
str2 is a random 8 character string.
In your particular example, none because the compiler internally uses StringBuilders to do String concatenation. If the concatenation occurred in a loop, however, the compiler could create several StringBuilder and String objects. For example:
String s= "" ;
for(int i= 0 ; i < 10 ; i++ )
s+= "a" ;
Each time line 3 above is executed, a new StringBuilder object is created, the contents of s appended, "a" appended, and then the StringBuilder is converted into a String to be assigned back to s. A total of 10 StringBuilders and 10 Strings.
Conversely, in
StringBuilder sb= new StringBuilder() ;
for(int i= 0 ; i < 10 ; i++ )
sb.append( "a" );
String s= sb.toString() ;
Only 1 StringBuilder and 1 String are created.
The main reason for this is that the compiler could not be smart enough to understand that the first loop is equivalent to the second and generate more efficient (byte) code. In more complex cases, it's impossible even for the smartest compiler to know. If you absolutely need this optimization, you have to introduce it manually by using StringBuilders explicitly.
The quick answer is the performance:
when you are using native String classes it operates immutable strings, which means when you are writing
String line = "java";
String sufix = " is awesome";
line = line + sufix;
it will create two strings "java" and " is awesome", than create a new third string "java is awesome" from previous two ("java" and "is awesome") which later are likely to be deleted by a garbage collector (because they are no more used in app). That is a slow solution.
More faster solution is an appliance of StringBuffer class which through the smart algorightms that provide a buffer (that is obvious from its name) for merging strings and as a result would not remove the initial string during the concatenation process.
In case you are writing single thread-application (no concurrancy issues during which multiple threads access same object) it is better to apply StringBuilder which has even faster performance than the initial StringBuffer class.