Table of contents
1. Why use StringBuilder and StringBuffer
2. StringBuilder and StringBuffer
StringBuffer source code explanation
4. The difference between StringBuilder and StringBuffer
1. Why use StringBuilder and StringBuffer
Before introducing StringBuilder and StringBuffer, we can review our previous string splicing operations. Most of them are spliced directly as follows:
public static void main(String[] args) {
String s = "hello";
s += " world";
System.out.println(s); // 输出:hello world
}
There is certainly no problem with such an operation, but if we talk about efficiency, the efficiency of such code is very low. Why is it so low? At this point we have to mention the related properties of strings.
String immutability
The String class is immutable when designed. We can see the following comments in the source code of JDK1.8
Therefore, the methods we usually use to operate String strings are to create a new object for operation. It is also very simple to verify this conclusion. We can choose a method at will. We use < a i=1>“ == ” is equivalent to comparing the hash values of the addresses of both variables, We compare a string with a string converted to uppercase
public static void main(String[] args) {
String s = "hello";
//s.toUpperCase(Locale.of(s));
System.out.println( s == s.toUpperCase(Locale.of(s)));
}
Output result:
Performance loss
Let’s review the splicing operation of strings just now. Each splicing requires a new object. When the number of splicings is very large, it will cause very serious performance problems. Of course, we can also verify this performance problem by using the currentTimeMillis method. To directly get the timestamp of the current system, we can use a loop to show the performance loss of using the traditional method of splicing strings.
public static void main(String[] args) {
long start = System.currentTimeMillis();
String s = " ";
for(int i = 0; i < 10000; ++i){
s += i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
Output result:
Of course, this is only 10,000 cycles, resulting in a running time of 82 milliseconds. The number of cycles required in actual projects is often immeasurable, so splicing in this way often cannot meet our performance requirements.
2. StringBuilder and StringBuffer
In order to solve the above problems, we can use StringBuilder and StringBuffer< a i=4> to perform string splicing and other operations. We can open API to see what StringBuilder and StringBuffer are
StringBuilder:
StringBuffer:
StringBuffer source code explanation
In general use, their functions are roughly the same. Here the author will only choose one of them for explanation. The overall methods and techniques used are mostly the same, so there is no need to worry about incomplete knowledge coverage. , the author takes StringBuffer as an example. We can use IDEA Open the source code of StringBuffer , we can find that it is also modified by final , Inherits the parent class AbstractStringBuilder and implements part of the interface
There are two member variables in parent classAbstractStringBuilder :
We can see that its construction method contains operations corresponding to different initializations:
Usage
By combining the super keyword in the source code with the member variables in the above parent class, we can get the following conclusion: We create a new one by default When a StringBuffer is actually created, a new one 16 bytes is created Array, we can also use the other two construction methods to directly pass in the size parameter or directly pass in a string when passing parameters
We summarizethree commonly used initialization methodsas follows:
- No parameters are passed, the default size is 16 bytes array
- Directly declare the size by passing in parameters
- Pass in string
StringBuffer stringBuffer1 = new StringBuffer();
StringBuffer stringBuffer3 = new StringBuffer(20);
StringBuffer stringBuffer2 = new StringBuffer("hello");
3. Summary of common methods
The biggest feature of ourStringBuilder and StringBuffer is They are internally variable. When we operate strings through these two classes, we do not need to create a new object. Therefore, we often use these two classes when splicing strings. This is extremely To a large extent, it helps us improve the efficiency of process operation
Let’s talk about the example mentioned at the beginning of the article again. We use StringBuffer’s append StringBuffer The a> here to compare the time required to splice characters. StringBuffer method can directly splice characters. We use traditional splicing characters and the
public static void main(String[] args) {
long start = System.currentTimeMillis();
String s = "";
for(int i = 0; i < 10000; ++i){
s += i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);
System.out.println("=======分割行========");
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);
}
Output result:
We can intuitively find that using StringBuffer to splice characters is more efficient than direct splicing Dozens of times, and if more cycles are added, this multiple can continue to increase. It is not a dream to increase the efficiency of the original program hundreds of times< /span>
In addition to the aboveappen method, we summarize the commonly used methods as follows:
method | illustrate |
StringBuff append(String str)
|
Additional part, equivalent value
String
target
+=
, Possible to add:
boolean
,
char
, < a i=9>char[]
, double, float, int< /span>, < /span>change amountStringBuff, StringObject, long,
|
char charAt(int index)
|
Get the character at
index
position
|
int length()
|
Get the length of a string
|
int capacity()
|
Get the total size of the underlying storage string space
|
void ensureCapacity(int mininmumCapacity)
|
Expansion
|
void setCharAt(int index, char ch)
|
Set the character at
index
to
ch
|
int indexOf(String str)
|
Return
str
The first occurrence of position
|
int indexOf(String str, int fromIndex)
|
Search from
fromIndex
position
str
for the first time where it appears
|
int lastIndexOf(String str)
|
Returns the position of the last occurrence
str
|
int lastIndexOf(String str, int fromIndex)
|
Start from
fromIndex
and find the last occurrence of
str
location
|
StringBuff insert(int
offset, String str)
|
Insert at position
offset
: eight base class types
& String< a i=4>Type
& ObjectType Data
|
StringBuffer deleteCharAt(int index)
|
删切
index
Position mark
|
StringBuffer delete(int start, int end)
|
Delete
[start, end)
Characters in the range
|
StringBuffer replace(int start, int end, String str)
|
Replace the characters at
[start, end)
with
str
|
String substring(int start)
|
Start
start
and end with characters
String
return
|
String substring(int start,
int end)
|
Convert
[start, end)
to
String
return
|
StringBuffer reverse()
|
Reverse a string
|
String toString()
|
Return all characters as
String
|
Example:
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("hello");
StringBuilder sb2 = sb1;
// 追加:即尾插-->字符、字符串、整形数字
sb1.append(' '); // hello
sb1.append("world"); // hello world
sb1.append(123); // hello world123
System.out.println(sb1); // hello world123
System.out.println(sb1 == sb2); // true
System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h
System.out.println(sb1.length()); // 获取字符串的有效长度14
System.out.println(sb1.capacity()); // 获取底层数组的总大小
sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123
sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123
System.out.println(sb1);
System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置
System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置
sb1.deleteCharAt(0); // 删除首字符
sb1.delete(0, 5); // 删除[0, 5)范围内的字符
String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回
System.out.println(str);
sb1.reverse(); // 字符串逆转
str = sb1.toString(); // 将StringBuffer以String的方式返回
System.out.println(str);
}
As can be seen from the above examples: String and StringBuilderThe biggest difference is that the content of String cannot be modified, while the content of StringBuilder can be modified, so consider using < if strings are frequently modified. a i=7>StringBuilder
Note: String and StringBuilder classes cannot be converted directly. If you want to convert each other, you can adopt the following principles:
- String becomes StringBuilder: Use StringBuilder’s construction method or append() method
- StringBuilder becomes String: CalltoString()method
4. The difference between StringBuilder and StringBuffer
We can open the source code ofStringBuffer, and we observe that almost everyStringBuffer There is one in front of synchronized to modify StringBuffer , heresynchronized can actually be understood as a lock, which issynchronized Modified methods are not allowed to be called by multiple objects at the same timeat the same time. This setting is for the safety of multi-threaded programs.
To give a popular example: Xiao Wang, Xiao Li, and Xiao Hong want to go to the toilet, but there is only one toilet. Xiao Wang goes to the toilet first, then Xiao Li or Xiao Hong can only wait for Xiao Wang to use the toilet and come out. After that, you can go to the toilet
And ourStringBuffer is set up like this. When an object is called, it issynchronized When a> modifies the method, this method will be locked and cannot be used by other objects. Only after the current object has used this method, that is, after it is unlocked, other objects can access it
When we open the source code ofStringBuilder we will find our StringBuilderThere is no such setting operation
Summarize:
That is to sayStringBuffer is for the safety of multi-threads, but frequent locking and unlocking will reduce the running efficiency of the code, and a>StringBuilder, if it is for high efficiency, useStringBufferAlthough there is no security consideration, it does not require unlocking, so it runs more efficiently. We use it if we need security in programmingStringBuilder
That’s it for this sharing. I hope my sharing can be helpful to you. I also welcome everyone’s support. Your likes are the biggest motivation for bloggers to update! If you have different opinions, you are welcome to actively discuss and exchange in the comment area, let us learn and make progress together! If you have relevant questions, you can also send a private message to the blogger. The comment area and private messages will be carefully checked. See you next time