1. An overview of the

Stringbuffer, Stringbuiler, Stringbuffer, Stringbuiler, Stringbuffer, Stringbuiler, Stringbuffer, Stringbuiler

So what is the difference between these three, how to choose to use according to the scenario, this article will be based on the source code of the three, performance, and interview questions to analyze.

String, StringBuffer, StringBuiler source code

The String class

Let’s start by looking at the class diagram of the String class, which implements the CharSequence interface, meaning that strings are of type CharSequence.

Underneath it is an array of characters modified by final, meaning that a String cannot be changed once it has been defined.

When we do string concatenation on a daily basis, it’s a process of creating new objects and recycling old objects. Take the following code for example:

String str = "a";
str += "b";
Copy the code

When the string STR is defined and the value “a” is assigned to it, when the second piece of code is executed, that is, when STR concatenates “B”, the JAVA VIRTUAL machine creates a new object STR and assigns the concatenated string “ab” to the new STR.

The GC also reclaims the old STR object, so the STR is not changed and is generated directly as a new object. If there is a lot of String concatenation, using String seriously affects performance.

Insert a picture description here

Insert a picture description here

StringBuffer class

Abstractstringbuffer class AbstractStringBuilder class abstractStringBuffer class AbstractStringBuilder class encapsulates a large number of basic methods, including array expansion mechanism, splicing method, etc.

A StringBuffer is initialized with a default length of 16 and is expanded by multiplying the old data by 2 and adding 2.

StringBuffer is thread-safe, as you can see from its Append method (shown below), modified by synchronized and therefore thread-safe.


@Override
public synchronized StringBuffer append(Object obj) {
    toStringCache = null;
    super.append(String.valueOf(obj));
    return this;
}

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}
Copy the code

Insert a picture description here

Insert a picture description here

StringBuiler class

StringBuilder is similar to StringBuffer, both of which inherit from AbstractStringBuilder, so their initial space and expansion mechanism are the same. The difference is that its append methods are not modified by synchronized and are therefore not thread-safe.

@Override
public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}
Copy the code

Insert a picture description here

Insert a picture description here

Comparison of String, StringBuffer, and StringBuilder performance

The test code is as follows

public class Test {

    private static final Integer time = 100000;

    public static void main(String[] args) {
        testString();
        testStringBuffer();
        testStringBuilder();
    }

    public static void testString() {
        String str = "";
        long start = System.currentTimeMillis();
        for (int i = 0; i < time; i++) { str +="a";
        }
        long end = System.currentTimeMillis();
        System.out.println("string:"+(end - start));
    }

    public static void testStringBuffer() {
        StringBuffer stringBuffer = new StringBuffer();
        long start = System.currentTimeMillis();
        for (int i = 0; i < time; i++) { stringBuffer.append("a");
        }
        long end = System.currentTimeMillis();
        System.out.println("stringBuffer:"+(end - start));
    }

    public static void testStringBuilder() {
        StringBuilder stringBuilder = new StringBuilder();
        long start = System.currentTimeMillis();
        for (int i = 0; i < time; i++) { stringBuilder.append("a");
        }
        long end = System.currentTimeMillis();
        System.out.println("stringBuilder:"+(end - start)); }}Copy the code

3.2 Test results are as follows:

Insert a picture description here

Conclusion: Executing the same concatenation of string “A” 100,000 times in a single thread takes a much longer time than StringBuffer and StringBuilder.

Examples of common interview questions

1. Judge the output result of the following program

String str1 = "helloworld";
String str2 = "hello" + "world";
System.out.println(str1 == str2); //true
Copy the code

2. Judge the output result of the following program

String str1 = "helloworld";
String str2 = "hello";
String str3 = str2+"world";
System.out.println(str1 == str3); //false
Copy the code

3. Judge the output result of the following program

String str1 = "helloworld";
final String str2 = "hello";
String str3 = str2+"world";
System.out.println(str1 == str3); //true
Copy the code

4. Judge the output result of the following program

public static void main(String[] args) {
    String str1 = "helloworld";
    final String str2 = returnStr();
    String str3 = str2 + "world";
    System.out.println(str1 == str3); //false
}

public static String returnStr() {
    return "hello";
}
Copy the code

5. Judge the output result of the following program

String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1 == str2); //false
Copy the code

6. Judge the output result of the following program

String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1 == str2.intern()); //true
Copy the code

5. Summary

1.String applies to situations where String concatenation is small and String changes are small.

2. Stringbuffers are used when string concatenations are frequent and are thread-safe (multithreaded).

3.StringBuiler works when string concatenation operations are frequent and are single-threaded.