A StringBuffer is used to create a single string from many strings, e.g. when you want to append parts of a String in a loop.
You should use a StringBuilder instead of a StringBuffer when you have only a single Thread accessing the StringBuffer, since the StringBuilder is not synchronized and thus faster.
AFAIK there is no upper limit for String size in Java as a language, but the JVMs probably have an upper limit.
Java provides the StringBuffer and String classes, and the String class is used to manipulate character strings that cannot be changed. Simply stated, objects of type String are read only and immutable. The StringBuffer class is used to represent characters that can be modified.
The significant performance difference between these two classes is that StringBuffer is faster than String when performing simple concatenations. In String manipulation code, character strings are routinely concatenated. Using the String class, concatenations are typically performed as follows:
String str = new String ("Stanford ");
str += "Lost!!";
If you were to use StringBuffer to perform the same concatenation, you would need code that looks like this:
StringBuffer str = new StringBuffer ("Stanford ");
str.append("Lost!!");
Developers usually assume that the first example above is more efficient because they think that the second example, which uses the append method for concatenation, is more costly than the first example, which uses the + operator to concatenate two String objects.
The + operator appears innocent, but the code generated produces some surprises. Using a StringBuffer for concatenation can in fact produce code that is significantly faster than using a String. To discover why this is the case, we must examine the generated bytecode from our two examples. The bytecode for the example using String looks like this:
The bytecode at locations 0 through 9 is executed for the first line of code, namely:
String str = new String("Stanford ");
Then, the bytecode at location 10 through 29 is executed for the concatenation:
str += "Lost!!";
Things get interesting here. The bytecode generated for the concatenation creates a StringBuffer object, then invokes its append method: the temporary StringBuffer object is created at location 10, and its append method is called at location 23. Because the String class is immutable, a StringBuffer must be used for concatenation.
After the concatenation is performed on the StringBuffer object, it must be converted back into a String. This is done with the call to the toString method at location 26. This method creates a new String object from the temporary StringBuffer object. The creation of this temporary StringBuffer object and its subsequent conversion back into a String object are very expensive.
In summary, the two lines of code above result in the creation of three objects:
A String object at location 0
A StringBuffer object at location 10
A String object at location 26
Now, let's look at the bytecode generated for the example using StringBuffer:
The bytecode at locations 0 to 9 is executed for the first line of code:
StringBuffer str = new StringBuffer("Stanford ");
The bytecode at location 10 to 16 is then executed for the concatenation:
str.append("Lost!!");
Notice that, as is the case in the first example, this code invokes the append method of a StringBuffer object. Unlike the first example, however, there is no need to create a temporary StringBuffer and then convert it into a String object. This code creates only one object, the StringBuffer, at location 0.
In conclusion, StringBuffer concatenation is significantly faster than String concatenation. Obviously, StringBuffers should be used in this type of operation when possible. If the functionality of the String class is desired, consider using a StringBuffer for concatenation and then performing one conversion to String.
Only in String class + operator is overloaded. We can concat two String object using + operator, but in the case of StringBuffer we can't.
String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides toString().
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2)); // output true
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb1.equals(sb2)); // output false
String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.
Set<StringBuffer> set = new TreeSet<StringBuffer>();
set.add(sb1);
set.add(sb2);
System.out.println(set); // gives ClassCastException because there is no Comparison mechanism
We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.
String is immutable but StringBuffer is mutable.
StringBuffer is synchronized, whereas String ain't.
StringBuffer is having an in-built reverse() method, but String dosen't have it.
String is used to manipulate character strings that cannot be changed (read-only and immutable).
StringBuffer is used to represent characters that can be modified.
Performance wise, StringBuffer is faster when performing concatenations. This is because when you concatenate a String, you are creating a new object (internally) every time since String is immutable.
You can also use StringBuilder which is similar to StringBuffer except it is not synchronized. The maximum size for either of these is Integer.MAX_VALUE (231 - 1 = 2,147,483,647) or maximum heap size divided by 2 (see How many characters can a Java String have?).
More information here.
String is an immutable class. This means that once you instantiate an instance of a string like so:
String str1 = "hello";
The object in memory cannot be altered. Instead you will have to create a new instance, copy the old String and append whatever else as in this example:
String str1 = "hello";
str1 = str1 + " world!";
What is really happening hear is that we are NOT updating the existing str1 object... we are reallocating new memory all together, copying the "hello" data and appending " world!" to the end, then settings the str1 reference to point to this new memory. So it really looks more like this under the hood:
So it follows that this "copy + paste and move stuff around in memory" process can be very expensive if done repitively especially recursively.
When you are in that situation of having to do things over and over utilize StringBuilder. It is mutable and can append strings to the end of the current one because it's back by an [growing array] (not 100% if that is the actual data structure, could be a list).
A StringBuffer or its younger and faster brother StringBuilder is preferred whenever you're going do to a lot of string concatenations in flavor of
string += newString;
or equivalently
string = string + newString;
because the above constructs implicitly creates new string everytime which will be a huge performance and drop. A StringBuffer / StringBuilder is under the hoods best to be compared with a dynamically expansible List<Character>.
A StringBuffer is used to create a single string from many strings, e.g. when you want to append parts of a String in a loop.
You should use a StringBuilder instead of a StringBuffer when you have only a single Thread accessing the StringBuffer, since the StringBuilder is not synchronized and thus faster.
AFAIK there is no upper limit for String size in Java as a language, but the JVMs probably have an upper limit.
I found interest answer for compare performance String vs StringBuffer by Reggie Hutcherso Source: http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Java provides the StringBuffer and String classes, and the String class is used to manipulate character strings that cannot be changed. Simply stated, objects of type String are read only and immutable. The StringBuffer class is used to represent characters that can be modified.
The significant performance difference between these two classes is that StringBuffer is faster than String when performing simple concatenations. In String manipulation code, character strings are routinely concatenated. Using the String class, concatenations are typically performed as follows:
If you were to use StringBuffer to perform the same concatenation, you would need code that looks like this:
Developers usually assume that the first example above is more efficient because they think that the second example, which uses the append method for concatenation, is more costly than the first example, which uses the + operator to concatenate two String objects.
The + operator appears innocent, but the code generated produces some surprises. Using a StringBuffer for concatenation can in fact produce code that is significantly faster than using a String. To discover why this is the case, we must examine the generated bytecode from our two examples. The bytecode for the example using String looks like this:
The bytecode at locations 0 through 9 is executed for the first line of code, namely:
Then, the bytecode at location 10 through 29 is executed for the concatenation:
Things get interesting here. The bytecode generated for the concatenation creates a StringBuffer object, then invokes its append method: the temporary StringBuffer object is created at location 10, and its append method is called at location 23. Because the String class is immutable, a StringBuffer must be used for concatenation.
After the concatenation is performed on the StringBuffer object, it must be converted back into a String. This is done with the call to the toString method at location 26. This method creates a new String object from the temporary StringBuffer object. The creation of this temporary StringBuffer object and its subsequent conversion back into a String object are very expensive.
In summary, the two lines of code above result in the creation of three objects:
Now, let's look at the bytecode generated for the example using StringBuffer:
The bytecode at locations 0 to 9 is executed for the first line of code:
The bytecode at location 10 to 16 is then executed for the concatenation:
Notice that, as is the case in the first example, this code invokes the append method of a StringBuffer object. Unlike the first example, however, there is no need to create a temporary StringBuffer and then convert it into a String object. This code creates only one object, the StringBuffer, at location 0.
In conclusion, StringBuffer concatenation is significantly faster than String concatenation. Obviously, StringBuffers should be used in this type of operation when possible. If the functionality of the String class is desired, consider using a StringBuffer for concatenation and then performing one conversion to String.
The differences are
String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides toString().
String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.
We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.
String
is used to manipulate character strings that cannot be changed (read-only and immutable).StringBuffer
is used to represent characters that can be modified.Performance wise,
StringBuffer
is faster when performing concatenations. This is because when you concatenate aString
, you are creating a new object (internally) every time sinceString
is immutable.You can also use
StringBuilder
which is similar toStringBuffer
except it is not synchronized. The maximum size for either of these isInteger.MAX_VALUE
(231 - 1 = 2,147,483,647) or maximum heap size divided by 2 (see How many characters can a Java String have?). More information here.String is an immutable class. This means that once you instantiate an instance of a string like so:
The object in memory cannot be altered. Instead you will have to create a new instance, copy the old String and append whatever else as in this example:
What is really happening hear is that we are NOT updating the existing str1 object... we are reallocating new memory all together, copying the "hello" data and appending " world!" to the end, then settings the str1 reference to point to this new memory. So it really looks more like this under the hood:
So it follows that this "copy + paste and move stuff around in memory" process can be very expensive if done repitively especially recursively.
When you are in that situation of having to do things over and over utilize StringBuilder. It is mutable and can append strings to the end of the current one because it's back by an [growing array] (not 100% if that is the actual data structure, could be a list).
A
StringBuffer
or its younger and faster brotherStringBuilder
is preferred whenever you're going do to a lot of string concatenations in flavor ofor equivalently
because the above constructs implicitly creates new string everytime which will be a huge performance and drop. A
StringBuffer
/StringBuilder
is under the hoods best to be compared with a dynamically expansibleList<Character>
.