Comparison of String, StringBuffer and StringBuilder in Java and source code analysis

Source: Internet
Author: User

Comparison of String, StringBuffer and StringBuilder in Java and source code analysis

It is well known that string, StringBuffer, and StringBuilder are common strings in Java, and I will compare the three brothers in three ways.

the data organization and its function realization of the first and third people

We love the string, StringBuffer, StringBuilder called the three brothers, after the analysis code found that they are a little less than three brothers, from the organizational structure, StringBuffer, StringBuilder more like a brother, The two brothers have a mother----abstractstringbuilder, that is, are inherited from the Abstractstringbuilder, and most of the "organs" are very similar, and string more like their cousin, the organization structure has similarities, But not exactly the same, let me start from the source code analysis of this brother three.

1, the three core code comparison (the above source code is from jdk1.7, and there are limitations)

String:

public final class String
    implements java.io.Serializable, comparable< String> charsequence {
     /** The value is used for character storage. */
em>      private final char  value [] ;

     /** Cache The hash code for the string * /
     public String () {
         This.value = new Char[0];
    }
     public String (string original) {
         this.value = Original.value;
        this.hash = Original.hash;
    }

Public String (char value[]) {
This.value = Arrays. copyOf (value, value.length);
}//Primary initialization function

}

Stringbuild:

Public final class StringBuilder
Extends Abstractstringbuilder
Implements Java.io.Serializable, Charsequence
{
    Public StringBuilder () {
Super (16);
}

    public StringBuilder (int capacity) {
Super (capacity);
}

    Public StringBuilder (String str) {
Super (Str.length () + 16);
Append (str);
}

    Public StringBuilder (charsequence seq) {
This (seq.length () + 16);
Append (seq);
}

StringBuffer:

Public final class StringBuffer
Extends Abstractstringbuilder
Implements Java.io.Serializable, Charsequence
{
    Public StringBuffer () {
Super (16);
}
    public stringbuffer (int capacity) {
Super (capacity);
}
    Public StringBuffer (String str) {
Super (Str.length () + 16);
Append (str);
}

    Public StringBuffer (charsequence seq) {
This (seq.length () + 16);
Append (seq);
}

The brothers were found to inherit the Abstractstringbuilder class, so it is necessary for us to call out this "mother" Abstractstringbuilder abstract class:

Abstractstringbuilder :

Abstract class Abstractstringbuilder implements Appendable, Charsequence {
char[] value;
int count;
Abstractstringbuilder () {
}
abstractstringbuilder (int capacity) {
Value = new Char[capacity];
}

2. The main differences between string and StringBuilder

As can be seen from the above code, this elder brother San du is a character array as a container to store strings, and the main difference is that the string is more than the remaining brothers a keyword final. What is final? Final is like the seal of the real, once it is covered, it will not change! Final can work on many things, such as if the class is final, the class is locked up and cannot be inherited. If the variable is final "covered", then the contents cannot be modified, so we can see that the value in string is final and non-modifiable. That is when we execute:

String Str=new string ("123");

This statement inside Java is the string class value[]={' 1 ', ' 2 ', ' 3 '}, and this value is not modifiable.

Then some people will say, if I do this next:

str = new String ("456");

Did you change the value of str? Here to figure out the non-modifiable meaning is that the contents of the memory is not modifiable, after the execution of this statement, in fact, did not modify the heap "123" Memory value, modified only the contents of the STR pointer.

The value values of the StringBuilder and StringBuffer brothers are not final modified, in other words, the string values can be modified, and it can be seen from the code that there are methods in the two classes append (increasing the string), Insert (dynamic Insert) and so on can change the string method. with these methods, the object is not regenerated, but rather on the basis of the original object, and the string is different, all of his methods are references to the string itself, there is no way to modify its own, it can be said that all the code modified by the string is the essence of creating a different object . Here's an example where we can easily modify the value of STR1 with code:

StringBuffer str1 = new StringBuffer ("Hello World");

Str1.append ("I am SK");

(Where the Append method is called the method of the string class GetChars the assignment of the character array, the most basic implementation by the Arraycopy to complete ... I can't help but say that your lap is messy)

3. The difference between StringBuffer and StringBuilder

It said that the difference between string and the two brothers is mainly can not change, then StringBuffer and StringBuilder What is the difference? The answer is on the keyword synchronized , you can see that the majority of the two brothers code is similar, the only difference is that stringbuffer in each method more than a "lock"---synchronized. In simple terms, it's thread safety.

Specifically, all classes or blocks of code that are synchronized "locked" have the following properties:

When two or more of the threads want to access the synchronized code block resource at the same time, only one thread can execute, and the other thread wants access to be queued, waiting for the thread to be used before it is accessed. This means that when a thread accesses the resource, it "locks" the resource (also called an exclusive lock, only the thread that has the exclusive lock can get the code block resource) so that other threads cannot use it.

So what's the use of thread safety? You think, because the contents of the StringBuilder and StringBuffer brothers can be modified, if there are multiple threads that want to change the contents of the string, if there is no thread lock, then the atomic operation may be divided into several parts, causing each thread to interact with each other and get the wrong operation.

In summary, string strings are non-modifiable (and, of course, thread-safe), StringBuilder strings and StringBuffer can be modified, where StringBuffer is thread-safe, StringBuilder does not guarantee thread safety.

Second, the design reason and influence

For such a good language in Java, the design of these three forms of string type is certainly not unfounded.

For string, the first question is why should be designed to be immutable, immutable more troublesome ah, directly to be able to change freely, and flexible and convenient. In fact, this is not the case, I think the string is designed to be immutable with the following benefits:

1, first, the string is set to immutable to a large extent to ensure security, in Java, the string is the most common way of data transmission, some data is private, such as the database password, and so on. These private data are strings, and it is the immutability of strings that guarantees the security of data passing.

2. Second, string is designed to be immutable for the implementation of a string constant pool, where the string constant pool is the stage in which the class file is compiled, and the strings in the code form a constant table (the detention string object) in the heap (jdk1.7) so that the next time you use string When you create an object or string, you go to the constant pool and look for the same detention string object, which saves you a lot of time to create. The constant pool is based on the immutable string, for example:

String str0= "Hello World";

String str1= "Hello World";

String str2= "Hello World";

Now there are three code, and there are four string objects in the heap with the value "Hello World", one in the constant pool, and three objects in the constant pool.

If the string class is modifiable, then if the strings in the constant pool are modified, then all the objects created by him are modified, which can cause confusion for the program, or if any one of the Strx modifies the value, the values in the constant pool are also modified, causing confusion. Therefore, the string cannot be changed is the constant pool technology implementation of the premise.

3. Finally, the string is not modifiable and thread-safe is ensured.

Sum up. It is necessary that the string be designed as immutable.

For Sringbuffer and StringBuilder, they are designed to be variable strings because it's fast and convenient when we want to modify a string and don't want to create a new object.

And then it's time to show the impact of the design on the three, the biggest effect is of course the speed of execution, in order to compare its speed when modifying a string (because it doesn't make much sense to compare the speed of a string object), I wrote the following test code to compare:

public class Stringcalsstest {
public static void Main (string[] args)
{
String str1= "";
StringBuffer str2=new StringBuffer ();
StringBuilder str3=new StringBuilder ();
Long Begintime=system.Currenttimemillis();
for (int i=0;i<10000;i++)
{
str1 = str1+ "Hello sk";
String Str5=new string ();
}
Long Endtime=system.Currenttimemillis();
System. out. printf ("String execution Speed:%d\n", endtime-begintime);
Begintime=system.Currenttimemillis();
for (int i=0;i<10000;i++)
{
Str2.append ("Hello SK");
StringBuffer str4=new StringBuffer ();
}
Endtime=system.Currenttimemillis();
System. out. printf ("StringBuffer Execution Speed:%d\n", endtime-begintime);
Begintime=system.Currenttimemillis();
for (int i=0;i<10000;i++)
{
Str3.append ("Hello SK");
StringBuilder str6=new StringBuilder ();
}
Endtime=system.Currenttimemillis();
System. out. printf ("StringBuilder Execution Speed:%d\n", endtime-begintime);

}
}

We also let the brothers do 10,000 times to add strings, and then compare their run time

The results of the operation are as follows:

You can see that using the string "+" operation to "modify" the string is very slow, and StringBuilder and StringBuffer is about 1000 times times worse. The reason for this is that we need to disassemble it with Jad:

Found

str1 = str1+ "Hello sk";

found that the disassembly of this sentence is

STR1 = (new StringBuilder ()). Append (str1). Append ("Hello sk"). ToString ();

Discover that every "+" operation was created StringBuilder object and used two times append method, that is, 10,000 operations he created 10,000 objects, so slow is inevitable, Both StringBuilder and StringBuffer operate directly on the original object.

So who is StringBuilder and stringbuffer faster than that? Since the previous example data volume is too small to see the comparison, we add the loop to 100,000 times to run again to get the result as follows:

You can see that stringbuffer is slower than StringBuilder, possibly due to a thread-safe operation that takes more time to lock the string.

In summary, the results of these three design differences are obvious: the string is immutable and the use of the "+" operator is very slow; the StringBuilder string is variable but the thread is unsafe; The StringBuffer string is variable and thread-safe.

III. application Scenarios for String, StringBuffer, StringBuilder

String: Used when the string is rarely modified or "+" is very small.

StringBuilder: Used when the string needs to be modified frequently and is a single-threaded application.

StringBuffer: Used when the string needs to be modified frequently and has multiple threads to access.

Iv. explain the results of the following code

1, String s1 = "Welcome to Java";

2, String s2 = new String ("Welcome to Java");

3, String s3 = "Welcome to Java";

4, System.out.println ("S1 = = S2 is" + (S1 = = s2));

5, System.out.println ("S1 = = S3 is" + (S1 = = S3));
First, the result of this code is false and ture.

Reason:

First, before compiling the class file, Java puts the string "Welcome to Java" into a string constant pool.

When the first sentence is executed, S1 points directly to the string in the constant pool. When executing the second sentence S2 creates a string object in the heap using the value of the "Welcome to Java" string in the constant pool. At the end of the third sentence, we found that "Welcome to Java" exists in the constant pool, so like S1, S3 points to a string in the constant pool.

At the end of the comparison, because "=" is used, the equals sign is the equivalent of two variables, and as you can see, S1 and S2 point to different, one to the string constant, one to the object in the heap, so the first sentence returns false. S1 and S3 all point to string constants, so return to ture.

Comparison of String, StringBuffer and StringBuilder in Java and source code analysis

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.