JAVA String, StringBuilder, and StringBuffer classes, java clears stringbuffer
The StringBuffer class (or StringBuilder) is the same as the String class and is also used to represent strings. However, because the internal implementation of StringBuffer is different from that of String, StringBuffer does not generate new objects during String processing, the memory usage is better than the String class.
Therefore, in actual use, if you often need to modify a string, such as insert and delete operations, StringBuffer is more suitable.
Many StringBuffer classes have the same methods as the String classes. These methods have the same functions as the String classes.
However, the most significant difference is that every modification to the StringBuffer object changes the object itself, which is the biggest difference with the String class.
In addition, because StringBuffer is thread-safe, there will be a special chapter on the concept of thread later, so it can be easily used in multi-threaded programs, however, the execution efficiency of the program is relatively slow.
1. StringBuffer object initialization
The initialization of the StringBuffer object is not the same as the initialization of the String class. Java provides special syntax, and generally uses the constructor for initialization.
For example:
StringBuffer s = new StringBuffer();
In this way, the initialized StringBuffer object is an empty object.
To create a StringBuffer object with content, you can use:
StringBuffer s = new StringBuffer ("abc ");
In this way, the content of the initialized StringBuffer object is the string "abc ".
Note that StringBuffer and String belong to different types and cannot be forced to convert them directly. The following code is incorrect:
StringBuffer s = "abc"; // The Value assignment type does not match tringBuffer s = (StringBuffer) "abc"; // There is no inheritance relationship, code that cannot perform inter-conversion between StringBuffer objects and String objects is as follows: String s = "abc"; StringBuffer sb1 = new StringBuffer ("123 "); stringBuffer sb2 = new StringBuffer (s); // String to StringBuffer String s1 = sb1.toString (); // StringBuffer to String
2. Common StringBuffer Methods
The methods in the StringBuffer class mainly focus on changing strings, such as append, insert, and delete. This is also the main difference between the StringBuffer and String classes.
A. append Method
Public StringBuffer append (boolean B)
This method is used to Append content to the end of the current StringBuffer object, similar to a string connection. After this method is called, the content of the StringBuffer object also changes. For example:
StringBuffer sb = new StringBuffer ("abc ");
Sb. append (true );
The sb value of the object is changed to "abctrue ".
Using this method to connect strings saves more content than strings. For example, it is used to connect database SQL statements. For example:
StringBuffer sb = new StringBuffer();String user = “test”;String pwd = “123”;sb.append(“select * from userInfo where username=“) .append(user) .append(“ and pwd=”) .append(pwd);
In this way, the sb value of the object is the string "select * from userInfo where username = test and pwd = 123 ".
B. deleteCharAt Method
Public StringBuffer deleteCharAt (int index)
The function of this method is to delete the characters at the specified position, and then form the remaining content into a new string. For example:
StringBuffer sb = new StringBuffer(“Test”);sb. deleteCharAt(1);
The purpose of this Code is to delete the character whose index value is 1 in the string object sb, that is, to delete the second character. The remaining content forms a new string. Therefore, the sb value of the object is changed to "Tst ".
There is also a function-like delete method:
Public StringBuffer delete (int start, int end)
This method is used to delete all characters within the specified range, including start, excluding the range of the end index value. For example:
StringBuffer sb = new StringBuffer(“TestString”);sb. delete (1,4);
The purpose of this Code is to delete all characters between index value 1 (inclusive) and index value 4 (excluded), and the remaining characters form a new string. The sb value of the object is TString ".
C. insert Method
Public StringBuffer insert (int offset, boolean B)
This method inserts content into the StringBuffer object and then forms a new string. For example:
StringBuffer sb = new StringBuffer(“TestString”);sb.insert(4,false);
The code in this example inserts the false value at the index value 4 of the object sb to form a new string. After the execution, the sb value of the object is "TestfalseString ".
D. reverse Method
Public StringBuffer reverse ()
This method is used to reverse the content in the StringBuffer object and form a new string. For example:
StringBuffer sb = new StringBuffer(“abc”);sb.reverse();
After conversion, the content in the object sb will become "CBA ".
E. setCharAt Method
Public void setCharAt (int index, char ch)
The function of this method is to modify the index value of an object to the index position of the new character ch. For example:
StringBuffer sb = new StringBuffer ("abc ");
Sb. setCharAt (1, 'D ');
The sb value of the object is changed to "aDc ".
F. trimToSize Method
Public void trimToSize ()
The function of this method is to reduce the storage space in the StringBuffer object to the same length as the string length, reducing the waste of space.
In short, in actual use, String and StringBuffer have their own advantages and disadvantages. You can select the corresponding type based on the specific use environment.
Comparison of String and StringBuffer Efficiency
The following code adds 26 English letters 10000 times to show more clearly their execution efficiency.
Public class Demo {public static void main (String [] args) {String fragment = "abcdefghijklmnopqrstuvwxyz"; int times = 10000; // use the String object long timeStart1 = System. currentTimeMillis (); String str1 = ""; for (int I = 0; I <times; I ++) {str1 + = fragment;} long timeEnd1 = System. currentTimeMillis (); System. out. println ("String:" + (timeEnd1-timeStart1) + "ms"); // use StringBuffer long timeStart2 = System. currentTimeMillis (); StringBuffer str2 = new StringBuffer (); for (int I = 0; I <times; I ++) {str2.append (fragment);} long timeEnd2 = System. currentTimeMillis (); System. out. println ("StringBuffer:" + (timeEnd2-timeStart2) + "ms ");}}
Running result:
String: 5287msStringBuffer: 3ms
Conclusion: The execution efficiency of StringBuffer is 30000 times faster than that of String. The difference is more and more obvious as the number of overlays increases. When the number of overlays reaches, the running result is:
String: 35923 ms
StringBuffer: 8 ms
Therefore, it is strongly recommended to use StringBuffer when a large number of string operations are involved.
StringBuilder class
The StringBuilder class and StringBuffer class have similar functions and methods. The main difference is that the StringBuffer class adopts multi-thread security, while StringBuilder is NOT thread-safe, the StringBuilder class is slightly faster.
The CharSequence interface is implemented in StringBuffer, StringBuilder, and String.
CharSequence is an interface that defines string operations. It only includes the length (), charAt (int index), and subSequence (int start, int end) APIs.
StringBuffer, StringBuilder, and String implement different CharSequence interfaces, as shown in:
It can be seen that String directly implements the CharSequence interface; StringBuilder and StringBuffer are variable character sequences, all of which inherit from AbstractStringBuilder and implement the CharSequence interface.
In the implementation of jdk, both StringBuffer and StringBuilder inherit from AbstractStringBuilder. For the Security and non-security of multithreading, you can see a bunch of synchronized before the method in StringBuffer.
We know that the use of StringBuffer is nothing more than to improve the efficiency of String connection in java, because if you directly use + for String connection, jvm will create multiple String objects, resulting in a certain amount of overhead.
AbstractStringBuilder uses a char array to store the string to be appended. the char array has an initial size. when the length of the append string exceeds the current char array capacity, the char array is dynamically expanded, that is, re-apply for a larger memory space, and then copy the current char array to the new location, because the overhead of re-allocating memory and copying is large, therefore, every time you re-apply for a memory space, you must apply for a memory space that is greater than the memory space you currently need. This is twice the size.
The classification is summarized as follows:
(1) During the append operation of StringBuffer, only the append operation is performed behind the string. The append process also needs to determine whether the size of the pre-stored array exceeds the 16 characters set at the beginning, you can then append the object. Each result will operate on the StringBuffer object itself, instead of generating a new object, and then changing the object reference .; Because both StringBuilder and StringBuffer are inherited from AbstractStringBuilder, The append method in the AbstractStringBuilder class is used for append operations, which shows all the overloaded append methods in the AbstractStringBuilder class, different functions can be implemented according to different requirements,
Take append (CharSequence s) as an example to illustrate: (the following methods are the methods in AbstractStringBuilder)
@Override public AbstractStringBuilder append(CharSequence s) { if (s == null) return appendNull(); if (s instanceof String) return this.append((String)s); if (s instanceof AbstractStringBuilder) return this.append((AbstractStringBuilder)s); return this.append(s, 0, s.length()); }
First, determine whether it is null, then determine which instance it is, and finally use the append Method for another overload:
@Override public AbstractStringBuilder append(CharSequence s, int start, int end) { if (s == null) s = "null"; if ((start < 0) || (start > end) || (end > s.length())) throw new IndexOutOfBoundsException( "start " + start + ", end " + end + ", s.length() " + s.length()); int len = end - start; ensureCapacityInternal(count + len); for (int i = start, j = count; i < end; i++, j++) value[j] = s.charAt(i); count += len; return this; }
Where:
/** * The count is the number of characters used. */ int count; /** * The value is used for character storage. */ char[] value;
We can see that:ensureCapacityInternal(count + len);
Is a process of resizing,value[j] = s.charAt(i);
It is the process of saving the append string. The specific process is to first resize the original StringBuffer object and then perform the append operation;
(2) The four construction methods of StringBuffer are as follows:
StringBuffer () is used to construct a string buffer with no characters. Its initial capacity is 16 characters. StringBuffer (CharSequence seq) public java. lang. StringBuilder (CharSequence seq) constructs a string buffer that contains the same characters as the specified CharSequence. StringBuffer (int capacity) constructs a string buffer with no characters but a specified initial capacity. StringBuffer (String str) constructs a String buffer and initializes its content to the specified String content.
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, a equivalence class used by a single thread is added for 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.
(3) For strings, although append (String concatenation) is implemented by creating StringBuilder objects and using the append method of StringBuilder, however, each append operation is a process of creating a StringBuilder object, because every change to the String type is equivalent to generating a new String object, then point the pointer to a New String object. The efficiency is obviously much lower than the direct use of StringBuilder. There are also many tests on the Internet, which fully demonstrates this point, 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;
(4) 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 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:
String S1 = “This is only a” + “ simple” + “ test”;StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
We are 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. In the JVM's eyes, This String S1 = "This is only a" + "simple" + "test ";
Actually: 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 a”;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.
The first step is as follows:In most cases, StringBuffer> String
(4) In general, StringBuilder is suitable for frequent append and delete operations. The original intention of the String design should be to use the process later, so as not to perform too many add and delete operations, after all, String is of the final type and is an immutable object. Therefore, they are all good at making reasonable choices based on their own needs;
Summary
Thread security:
StringBuffer: thread security
StringBuilder: thread security
Speed:
Generally, the speed from fast to slow is StringBuilder> StringBuffer> String. Of course, this is relative, not absolute.
Environment:
Operate a small amount of data using String;
Use StringBuilder to operate a large amount of data in a single thread;
Use StringBuffer for multi-threaded operations on a large amount of data.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.