What is the difference between String and StringBuffer in Java?
Asked Answered
T

15

63

What is the difference between String and StringBuffer in Java?

Is there a maximum size for String?

They answered 13/3, 2010 at 17:25 Comment(1)
In the future, you can look at javadocs for this type of question. Java 6 javadocs: java.sun.com/javase/6/docs/api String: java.sun.com/javase/6/docs/api/java/lang/String.html StringBuffer: java.sun.com/javase/6/docs/api/java/lang/StringBuffer.htmlSeamanlike
V
76

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.

Viperine answered 13/3, 2010 at 17:28 Comment(5)
Can you give a source for the length?Mozza
@Thomas java.sun.com/javase/6/docs/api/java/lang/Integer.html#MAX_VALUE If you put 2^31 - 1 into google you get 2,137,483,647Viperine
I meant a source for why Strings can not be longer and, probably more importantly, why one can assume that they can be Integer.MAX_VALUE characters long and not just e.g. 2^16. As noted in my other answer, String literals can only be 2^16 since they need to fit into the constant pool.Mozza
@Thomas, internally Java represents the length of characters in the character array by an int. So that's the theoretical length.Viperine
@Thomas:If I had a string literal in my program of size 2^17, couldn't it be broken up into two string literals of size 2^16 in the class file and then concatenated at runtime? And the JVM spec can change as well. The Javadocs are the contract.Stephine
A
35

A String is immutable, i.e. when it's created, it can never change.

A StringBuffer (or its non-synchronized cousin StringBuilder) is used when you need to construct a string piece by piece without the performance overhead of constructing lots of little Strings along the way.

The maximum length for both is Integer.MAX_VALUE, because they are stored internally as arrays, and Java arrays only have an int for their length pseudo-field.

The performance improvement between Strings and StringBuffers for multiple concatenation is quite significant. If you run the following test code, you will see the difference. On my ancient laptop with Java 6, I get these results:

Concat with String took: 1781ms
Concat with StringBuffer took: 0ms
public class Concat
{
    public static String concatWithString()
    {
        String t = "Cat";
        for (int i=0; i<10000; i++)
        {
            t = t + "Dog";
        }
        return t;
    }
    public static String concatWithStringBuffer()
    {
        StringBuffer sb = new StringBuffer("Cat");
        for (int i=0; i<10000; i++)
        {
            sb.append("Dog");
        }
        return sb.toString();
    }
    public static void main(String[] args)
    {
        long start = System.currentTimeMillis();
        concatWithString();
        System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
        start = System.currentTimeMillis();
        concatWithStringBuffer();
        System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
    }
}
Adamant answered 13/3, 2010 at 17:28 Comment(0)
G
25
String                                          StringBuffer

Immutable                                       Mutable
String s=new String("karthik");                StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy");                             sb.append("reddy");
System.out.println(s);                         System.out.println(sb);
O/P:karthik                                    O/P:karthikreddy

--->once we created a String object            ---->once we created a StringBuffer object
we can't perform any changes in the existing  we can perform any changes in the existing
object.If we are trying to perform any        object.It is nothing but mutablity of 
changes with those changes a new object       of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object

Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety

String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object

String s="karthik"; 
--->In this case only one object will be created in scp and s is always pointing to that object only
Gurley answered 22/3, 2013 at 6:54 Comment(1)
really? String s=new String("karthik"); it will create two objects?Whisenhunt
N
11

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:

String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;

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).

Novocaine answered 4/3, 2011 at 16:58 Comment(0)
U
4

From the API:

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

Ulster answered 4/3, 2011 at 16:50 Comment(0)
P
2

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.

Peregrine answered 13/3, 2010 at 17:27 Comment(2)
Strings have a toCharArray() method though, and this has to return the full contents of the string according to the javadoc.Adamant
@Simon Nickerson Thanks, so the upper limit then is no more than Integer.MAX_VALUE.Mozza
D
2

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:

 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:

0 new #7 <Class java.lang.String>
3 dup 
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1

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:

  1. A String object at location 0
  2. A StringBuffer object at location 10
  3. A String object at location 26

Now, let's look at the bytecode generated for the example using StringBuffer:

0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1 
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop

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.

Daiseydaisi answered 23/11, 2010 at 6:55 Comment(1)
Choosing between String vs StringBuffer/Builder shouldn't really be a question that anyone should care about.... The JVM is a JIT environment -> why cant the JIT perform a suitable optimisation?Indican
B
2

By printing the hashcode of the String/StringBuffer object after any append operation also prove, String object is getting recreated internally every time with new values rather than using the same String object.

public class MutableImmutable {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println("String is immutable");
    String s = "test";
    System.out.println(s+"::"+s.hashCode());
    for (int i = 0; i < 10; i++) {
        s += "tre";
        System.out.println(s+"::"+s.hashCode());
    }

    System.out.println("String Buffer is mutable");

    StringBuffer strBuf = new StringBuffer("test");
    System.out.println(strBuf+"::"+strBuf.hashCode());
    for (int i = 0; i < 10; i++) {
        strBuf.append("tre");
        System.out.println(strBuf+"::"+strBuf.hashCode());
    }

 }

}

Output: It prints object value along with its hashcode

    String is immutable
    test::3556498
    testtre::-1422435371
    testtretre::-1624680014
    testtretretre::-855723339
    testtretretretre::2071992018
    testtretretretretre::-555654763
    testtretretretretretre::-706970638
    testtretretretretretretre::1157458037
    testtretretretretretretretre::1835043090
    testtretretretretretretretretre::1425065813
    testtretretretretretretretretretre::-1615970766
    String Buffer is mutable
    test::28117098
    testtre::28117098
    testtretre::28117098
    testtretretre::28117098
    testtretretretre::28117098
    testtretretretretre::28117098
    testtretretretretretre::28117098
    testtretretretretretretre::28117098
    testtretretretretretretretre::28117098
    testtretretretretretretretretre::28117098
    testtretretretretretretretretretre::28117098
Biel answered 23/6, 2016 at 6:2 Comment(0)
D
1

A String is an immutable character array.

A StringBuffer is a mutable character array. Often converted back to String when done mutating.

Since both are an array, the maximum size for both is equal to the maximum size of an integer, which is 2^31-1 (see JavaDoc, also check out the JavaDoc for both String and StringBuffer).This is because the .length argument of an array is a primitive int. (See Arrays).

Dynamoelectric answered 13/3, 2010 at 17:29 Comment(8)
Can you give a source for the maximum length?Mozza
The length of an array is an int, which is a signed 32-bit value. The value Pindatjuh quotes is Integer.MAX_VALUE, which is correct. But the classes themselves do not impose this maximum length, and so in a sense Pindatjuh is incorrect, as he is looking behind the curtain at the implementation. There is no reason why String could not be implemented as a char[][], which would then be limited to Long.MAX_VALUE, and so on.Stephine
@Thomas Lötzer added sources.Dynamoelectric
Where in the JLS does it say that a String has to be implemented as a single array? Also: String literals can not be Integer.MAX_VALUE characters long, since they are put into the constant pool. They can only be 2^16 characters. How can one be sure that such limits are not present for other Strings as well?Mozza
@Thomas Lötzer, the question is not related to a source-code file. In runtime a String can be of length 2^31-1. The implementation of String is open-source, check it out, how it's implemented.Dynamoelectric
@GregS: however, String has a toCharArray() method, which could not be implemented if you had a String longer than Integer.MAX_VALUE characters.Adamant
@Dynamoelectric there are more JVMs than OpenJDK. J9, CremeVM, Jrockit, ... Not all of them are open source and some of them are specialized on very constrained devices such as low-end cell phones. It would be interesting to know if there is a lower limit to the supported String size on such devices.Mozza
@Simon: I agree, that method and the charAt method imply that a String is limited to Integer.MAX_VALUE characters.Stephine
O
1

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>.

Obsolesce answered 13/3, 2010 at 17:29 Comment(0)
U
1

String is immutable, meaning that when you perform an operation on a String you are really creating a whole new String.

StringBuffer is mutable, and you can append to it as well as reset its length to 0.

In practice, the compiler seems to use StringBuffer during String concatenation for performance reasons.

Uterine answered 4/3, 2011 at 16:50 Comment(0)
E
1
String is immutable. 

Why? Check here.

StringBuffer is not. It is thread safe. 

Further questions like when to use which and other concepts can be figured out following this.

Hope this helps.

Enschede answered 25/7, 2013 at 6:44 Comment(0)
D
1

While I understand that this is not a major differentiating factor, I noticed today that StringBuffer(and StringBuilder) provides some interesting methods that String doesn't.

  • reverse()
  • setCharAt()
Dumb answered 20/11, 2014 at 3:14 Comment(0)
M
1

The differences are

  1. Only in String class + operator is overloaded. We can concat two String object using + operator, but in the case of StringBuffer we can't.
  2. 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
    
  3. 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
    
  4. We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.

  5. String is immutable but StringBuffer is mutable.
  6. StringBuffer is synchronized, whereas String ain't.
  7. StringBuffer is having an in-built reverse() method, but String dosen't have it.
Marcille answered 17/1, 2017 at 13:28 Comment(0)
M
0

Performance wise StringBuffer is much better than String ; because whenever you apply concatenation on String Object then new String object are created on each concatenation.

Principal Rule : String are immutable(Non Modifiable) and StringBuffer are mutable(Modifiable)

Here is the programmatic experiment where you get the performance difference

public class Test {

  public static int LOOP_ITERATION= 100000;

  public static void stringTest(){
    long startTime = System.currentTimeMillis();
    String string = "This";
    for(int i=0;i<LOOP_ITERATION;i++){
        string = string+"Yasir";
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);    
  }

  public static void stringBufferTest(){
    long startTime = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer("This");
    for(int i=0;i<LOOP_ITERATION;i++){
        stringBuffer.append("Yasir");
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
  }

  public static void main(String []args){
    stringTest()
    stringBufferTest(); 
  }
 }

Output of String are in my machine 14800

Output of StringBuffer are in my machine 14

Maxfield answered 11/6, 2016 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.