Study Notes of the String Class (Part 2): String Concatenation and Learning of StringBuilder and StringBuffer

This article introduces the String class's method of splicing strings and the efficiency analysis of splicing strings, as well as the common methods and differences of the StringBuilder and StringBuffer classes that can modify the string content, and finally introduces two classic string interview questions

1. String class summary

1. String common method learning -> 2. String immutability and string constant pool -> StringBuilder and StringBuffer

The String class is a class used to describe and manipulate strings in Java.
The last two blogs introduced the commonly used methods and the characteristics of String: the content of String is immutable and the string constant pool. If you are interested, you can go and have a look...

Two. StringBuilder and StringBuffer

StringBulder and StringBuffer are classes that operate on strings just like String.
After learning String, we know that the content of String is immutable. Modifying the content of String will create a new string and return it.

However, creating a new String object takes more time and space than modifying the original string, and the efficiency is much lower.

Therefore, StringBuilder and StringBuffer provided in java are classes specially used to modify strings in place, and they can all be converted to and from the String class

insert image description here
insert image description here
Through the source code, we can see that the methods of these two classes are roughly the same, and both extend inherit the AbstractStringBuilder class

insert image description here
At the bottom of the AbstractStringBuilder class, there is a value array reference and count variable, which can be accessed in StringBuilder and StringBuffer without being modified by private and final

The value array maintains the string content, and the count records the number of valid characters in the value, that is, the real string length

(Because the length of the character array pointed to by value is the space for storing the string currently, and there is reserved space for adding new characters, etc., the count records the real length of the string)

Due to the immutable characteristics of String, in order to facilitate the modification of strings, Java also provides StringBuilder and StringBuffer classes. Most of the functions of these two classes are the same

1. String concatenation

Provide concat and join methods in the String method to splice strings

insert image description here

concat is a member method that connects the content of a string object with another string object to return a new string object
insert image description here

join is a static member method. The first parameter of the method is the delimited string for connection, and the following 2~n strings are used for connection, which will be spliced ​​together and separated by a parameter (each segment of the string separated by the connection , if there is only one paragraph, the separator will not be displayed), and finally return the concatenated string object

insert image description here

However, the above methods do not have the function of splicing data of other data types into strings, so when using these methods, data of other non-String types must be spliced ​​and converted to strings before splicing.

In Java, the String type uses + to connect String string data and any type of data to make it simple, quick and direct splicing into a new string object.
Example:

public static void main(String[] args) {
    
    

        System.out.println("12"+3);
        System.out.println(3+"12");
        System.out.println(1+2+"12");
        System.out.println("12"+1+2);
        System.out.println(false+"12"+true);
        //代码输出结果是什么?
    }

insert image description here
Using the + operation between string type data and any data type data can be spliced ​​into a new string object.

But pay attention to the priority of the operator, 1+2+"12" is to calculate 1+2 first and the result is 3, then 3+"12" is spliced ​​into the string "312"

"12"+1+2, first "12"+1 is spliced ​​into a string "121" and then +2 is spliced ​​into a string "1212"

boolean type data can participate in string splicing

""+12 can make 12 digits spliced ​​into a string "12"

String splicing can be quickly realized through the + sign, which is very convenient and allows us to quickly change the basic data type into a string type

StringBuilder and StringBuffer can also implement string splicing, which needs to call its internal append method:

public static void main(String[] args) {
    
    
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(1+2);
        stringBuilder.append(12);
        System.out.println(stringBuilder);
        stringBuilder.append(3);
        System.out.println(stringBuilder);
        stringBuilder.append(false);
        System.out.println(stringBuilder);
 }

insert image description here

It can be seen that any data type can be spliced ​​into a string by using the append method of the StringBuilder object,
insert image description here
and the last return in the append method is the StringBuilder object itself, and no new object is created...

In terms of operating efficiency, which is better to use + and other data splicing, StringBuiler and the append method of the String type?

At this time, you can use System.currentTimeMillis(), a method in Java to calculate the internal running time, to take a difference operation to test the running time of these three...
Example:

public static void main(String[] args) {
    
    
        long start = System.currentTimeMillis();  // 计算当前内部运行时间
        String s = "";

        for(int i = 0; i < 10000; ++i){
    
    
            s += i;                             //字符串类型 加任意基本数据类型 都会拼接成一个新字符串再给s引用接收
        }   // 每+=一次 会额外创建三个对象
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");  // 需要加锁解锁
        for(int i = 0; i < 10000; ++i){
    
    
            sbf.append(i);                     //对字符串内的数组进行操作 不会创建额外字符串
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
    
    
            sbd.append(i);                 //对字符串内的数组进行操作 不会创建额外字符串
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }

insert image description here
It can be roughly estimated by running the results: Splicing efficiency: String<StringBuffer<StringBuilder

Why is String type using + for string concatenation much slower than StringBuilder and StringBuffer?

Disassemble this file through the javap -c bytecode file, and you can see what has been done at the bottom using the + sign. Using
insert image description here
+ for splicing is essentially to create a new StringBuilder object first, and then call the append method to append the s string to it. , and then call append to append i, and finally call the toString method to return~

insert image description here
And StringBuilder rewrites the toString method, its role is to instantiate a new String object,
pass the array pointed to by the value array reference of AbstractStringBuilder inherited by StringBuilder and 0, count as parameters to call its construction method,

The function is to create a String object whose content is the content between 0 and count of the array object pointed to by value (note: the value in String is the new value array pointed to)

It can be seen that using the + sign to concatenate strings uses the append method of the StringBuilder object at the bottom, and finally returns a new String object...

In the above code, 10,000 i are spliced ​​through the + sign using the for loop, and a StringBuilder object and a String object will be created for each splicing. It can be seen that so many new objects are needed to complete this operation, and the unpointed ones must be recycled. String object, consumes a lot

The direct instance of the StringBuilder object appends the string content through append. After all the appending is completed, it only needs to convert the StringBuilder object into a String object for one operation. In this operation, only two additional objects are instantiated, and the overhead is less than that of the + sign. many

Therefore: when using a large number of string append operations, it is not recommended to use the + operator for splicing, its performance is far lower than using StringBuilder for append splicing, and using StringBuilder is more efficient than other splicing methods

("1"+"2" string constants are concatenated with the + sign, and the above append will not be performed, and the underlying layer will be directly regarded as a "12" string)

2. Common methods and differences between StringBuilder and StringBuffer

Both StringBuilder and StringBuffer can modify strings, and most of their internal methods are the same. The
following are some commonly used methods that can modify string content, such as:

method effect
append() Append at the end, which is equivalent to += of String, and can be appended: variables of boolean, char, char[], double, float, int, long, Object, String, StringBuff
void setCharAt(int index,char ch) Set the character at index position to ch
insert(int offset, String str) Insert at offset position: eight base class types & String type & Object type data
deleteCharAt(int index) Delete the index position character
delete(intstart, int end) Delete the characters in the interval [start, end)
replace(intstart, int end, String str) Replace the characters at [start, end) with str
reverse() reverse the string in place
toString() Return the content as a String object

The above are the methods commonly used by StringBulider and StringBuffer to modify the string content. There are also some methods like the Stirng class, such as indexOf(). You can learn more about it yourself.

Since most of the methods are the same, what is the specific difference between these two classes?

Because the String class cannot modify the string, its design can make threads safer. Each thread calls a method to create a new string object, and StringBuilder can modify the string content, which will result in multiple threads. Simultaneously calling a method can create some problems... this is the time to solve this thread-unsafe problem

insert image description here
insert image description here
It can be seen from the source code that most of the methods in StringBuffer are decorated with the synchronized (synchronization) keyword. The method modified by this keyword is a synchronized method, which is thread-safe, which means that in the case of multiple threads, different threads simultaneously When this method is called, it will be locked. Only one thread can execute this method at a time, and other threads can only execute this method one by one after executing this method and unlocking it.

When the above StringBuffer and StringBuilder objects splice 10,000 i, StringBuilder is a little more efficient than it, and it is also because StringBuffer needs to perform lock and unlock operations when executing methods, which also consumes resources...

Therefore, the StringBuffer class is used in multi-threaded situations to modify string objects while StringBuilder is used in single-threaded situations

3. Interview question: How many objects are created by the following code?

 public static void main(String[] args) {
    
    

        String str=new String("123");  // 创建多少个对象
        String str1=new String("1"+"2")+new String("3"); //创建多少个对象
//以上程序在运行时字符串常量都是第一次出现字符串常量池并不存在程序中的常量字符串
    }

When the program is running, str code a "123" object and store it in the string constant pool, new String() an object; finally create two String objects

At str1, first create a new StringBuilder object and then new String() an object, "1"+"2" is directly programmed into "12" which is a String object, and then spliced ​​into the StringBuilder, and then in the new String object, then " 3" An object is spliced ​​into the StringBuilder object, and finally StringBuilder calls toString and returns a new String object, and finally new 1 StringBuilder object and five String objects

Note that the last string content accepted by str1 is 123, but it is different from "123" in the string constant pool. The
string constant pool stores its string constant "123" at compile time, while str1 accepts Subsequent concatenated string 123

insert image description here

4. Interview questions: Similarities and differences between String, StringBuilder and StringBuffer

All three are classes used to describe the manipulation of strings

The content of the String class is immutable, and all operations to modify the content of the String are to create a new String object

, the contents of StringBuilder and StringBuffer are variable, and are often used when frequently modifying string contents.

Most of the functions of StringBuffer and StringBuilder are similar

StringBuffer uses synchronous processing, which is a thread-safe operation; while StringBuilder does not use synchronous processing, which is a thread-unsafe operation

3. Summary

This article introduces the method of string concatenation (the member method concat of String and the join + sign operator of the class member concatenation of StringBuilder and StringBuffer's append concatenation), as well as the efficiency of various splicing methods and the underlying disassembly analysis, most of StringBuffer and StringBuilder The method of modifying the content, and its differences, as well as the interview questions and analysis of the two major character strings

insert image description here

Guess you like

Origin blog.csdn.net/lch1552493370/article/details/130654863