Differences between String, StringBuffer, and StringBuilder in Java

Source: Internet
Author: User

I believe that you have already understood the differences between String and StringBuffer, but it is estimated that many comrades may not be clear about the working principles of these two classes, today, I will review this concept here. By the way, we will find a new class for character operations in J2SE 5.0-StringBuilder. So what are the differences between this StringBuilder and StringBuffer and the String class we first met? Which one should we use in different scenarios? I want to share my own views on these categories. I also hope that you can put forward your comments. If everyone has a mistake, it is a good opportunity to learn at the same time.

In short, the main performance difference between the String type and the StringBuffer type is that the String type is an immutable object (why? Ask the Java designer why is String not of the native type ?) Therefore, every time the String type is changed, it is equivalent to generating a new String object, and then pointing the pointer to the New String object, therefore, it is best not to use a String that often changes the content, because every time an object is generated, it will affect the system performance, especially when there are more referenced objects in the memory, the GC of JVM will start to work, and the speed will be quite slow. Here is an incorrect example:Copy codeThe Code is as follows: String S1 = "abc ";
For (int I = 0; I <10000; I ++) // multiple calls of the For simulation program
{
S1 + = "def ";
S1 = "abc ";
}

If so, after this for loop is complete, if the objects in the memory are not cleared by GC, there will be more than 20 thousand objects in the memory, an astonishing number, if this is a system that many people use, this number is not much, so you must be careful when using it.

If the StringBuffer class is used, the results will be different. Each result will operate on the StringBuffer object itself, instead of generating a new object, and then change the object reference. Therefore, we generally recommend using StringBuffer, especially when string objects change frequently. In some special cases, the String concatenation of the String object is actually interpreted by JVM as the concatenation of the StringBuffer object. Therefore, the speed of the String object in these cases is not slower than that of the StringBuffer object, in particular, in the generation of the following String objects, the String efficiency is much faster than that of StringBuffer:

Copy codeThe Code is as follows: String S1 = "This is only a" + "simple" + "test ";
StringBuffer Sb = new StringBuilder ("This is only a"). append ("simple"). append ("test ");

You will be surprised to find that the speed of generating the String S1 object is too fast, and the StringBuffer speed is not dominant at all. In fact, this is a JVM trick.Copy codeThe Code is as follows: String S1 = "This is only a" + "simple" + "test"; in fact, it is: String S1 = "This is only a simple test "; so of course it does not take too much time. However, you should note that if your String is from another String object, the speed will not be so fast. For example:
String S2 = "This is only ";
String S3 = "simple ";
String S4 = "test ";
String S1 = S2 + S3 + S4;

At this time, the JVM will follow the original method in a regular manner, and the generation speed of the S1 object is not as fast as it was just now. In a moment, we can come to a test for verification.

From this, we get the first conclusion: In most cases, StringBuffer> String

What if StringBuilder compares with them? First, let's briefly introduce StringBuilder, a newly added class in JDK. For the difference between StringBuffer and StringBuffer, see the following introduction (Source: JavaWorld ):

Java. lang. StringBuffer thread-safe variable character sequence. It is similar to the String buffer, but cannot be modified. The string buffer can be safely used for multiple threads. These methods can be synchronized as necessary, so all the operations on any specific instance are in serial order, this sequence is consistent with the method call sequence of each involved thread.

Each string buffer has a certain capacity. As long as the length of the Character Sequence contained in the string buffer does not exceed this capacity, no new internal buffer array needs to be allocated. If the internal buffer overflow occurs, the capacity increases automatically. From JDK 5.0, an equivalent class used by a single thread is added to this class, that is, StringBuilder. Compared with this class, the StringBuilder class should be used first, because it supports all the same operations, but because it does not execute synchronization, It is faster.

However, it is not safe to apply StringBuilder instances to multiple threads. If such synchronization is required, StringBuffer is recommended.

In this case, we can all understand the differences between them, so let's make a general deduction:

In most cases, StringBuilder> StringBuffer

Therefore, according to the transfer theorem of this inequality: In most cases, StringBuilder> StringBuffer> String

Now that we have such a derivation result, let's test and verify it:

The test code is as follows:Copy codeThe Code is as follows: public class testssb {

/** Creates a new instance of testssb */
Final static int ttime = 10000; // number of test cycles
Public testssb (){
}

Public void test (String s ){
Long begin = System. currentTimeMillis ();
For (int I = 0; I <ttime; I ++ ){
S + = "add ";
}
Long over = System. currentTimeMillis ();
System. out. println ("operation" + s. getClass (). getName () + "type:" + (over-begin) + "millisecond ");
}

Public void test (StringBuffer s ){
Long begin = System. currentTimeMillis ();
For (int I = 0; I <ttime; I ++ ){
S. append ("add ");
}
Long over = System. currentTimeMillis ();
System. out. println ("operation" + s. getClass (). getName () + "type:" + (over-begin) + "millisecond ");
}

Public void test (StringBuilder s ){
Long begin = System. currentTimeMillis ();
For (int I = 0; I <ttime; I ++ ){
S. append ("add ");
}
Long over = System. currentTimeMillis ();
System. out. println ("operation" + s. getClass (). getName () + "type:" + (over-begin) + "millisecond ");
}

// Directly concatenate strings.
Public void test2 (){
String s2 = "abadf ";
Long begin = System. currentTimeMillis ();
For (int I = 0; I <ttime; I ++ ){
String s = s2 + s2 + s2;
}
Long over = System. currentTimeMillis ();
System. out. println ("Operation String object reference addition type used:" + (over-begin) + "millisecond ");
}

Public void test3 (){
Long begin = System. currentTimeMillis ();
For (int I = 0; I <ttime; I ++ ){
String s = "abadf" + "abadf" + "abadf ";
}
Long over = System. currentTimeMillis ();
System. out. println ("the time for adding operation strings is:" + (over-begin) + "millisecond ");
}

Public static void main (String [] args ){
String s1 = "abc ";
StringBuffer sb1 = new StringBuffer ("abc ");
StringBuilder sb2 = new StringBuilder ("abc ");

Testssb t = new testssb ();
T. test (s1 );
T. test (sb1 );
T. test (sb2 );
T. test2 ();
T. test3 ();
}
}

The above code is compiled on NetBeans 5.0 IDE/JDK1.6, and The ttime of the loop is 10000. The test result is as follows:
The time used to operate java. lang. String is 4392 milliseconds.
Java. lang. StringBuffer operation time: 0 ms
Java. lang. StringBuilder operation time: 0 ms
Operation String object reference addition type time: 15 ms
Operation string addition time: 0 ms

It seems that there is no difference between StringBuffer and StringBuilder. Add the ttime to 30000 times:
The time used to operate java. lang. String is 53444 milliseconds.
Java. lang. StringBuffer operation time: 15 ms
Java. lang. StringBuilder operation time: 15 ms
Operation String object reference addition type time: 31 Ms
Operation string addition time: 0 ms

The performance of StringBuffer and StringBuilder is not significantly different. increase it to 100000. Here we will not add the String type test, because the testing of the large data volume of the String type will be slow ......
Java. lang. StringBuffer operation time: 31 Ms
The time used to operate java. lang. StringBuilder is 16 milliseconds.

We can see the difference, but there are many tests that show that the StringBuffer is faster than the StringBuilder, and then increase it to 1000000 (should it not be a machine ?) :
The time used to operate the java. lang. StringBuffer type is 265 milliseconds.
The time used to operate java. lang. StringBuilder is 219 milliseconds.

There are few differences, and the results are very stable. Let's look at it again, ttime = 5000000:

· Exception in thread "main" java. lang. OutOfMemoryError: Java heap space ······

Well, forget it. If you don't want to test it, it's basically all about the performance of StringBuilder> StringBuffer> String.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.