Home > Java > javaTutorial > body text

Analysis of the differences between String, StringBuffer and StringBuilder in Java

高洛峰
Release: 2017-01-22 11:41:36
Original
1464 people have browsed it

I believe that everyone has a good understanding of the difference between String and StringBuffer, but it is estimated that many comrades are still unclear about the working principles of these two classes. Today I will review this concept for everyone. By the way, a new character operation class brought in J2SE 5.0 - StringBuilder. So what are the differences between this StringBuilder and StringBuffer and the String class we first met? Which one should we use in different situations? I would like to share my views on these categories, and I also hope that everyone can give their opinions. Everyone has made mistakes, and while correcting them, it is a good opportunity to learn.

Briefly speaking, the main performance difference between the String type and the StringBuffer type is that String is an immutable object (Why? Ask the designers of Java, why is String not a native type?) Therefore, every time When changing the String type, it is actually equivalent to generating a new String object, and then pointing the pointer to the new String object. Therefore, it is best not to use String for strings that frequently change content, because each time an object is generated, it will affect the system performance. Especially when there are too many unreferenced objects in the memory, the JVM's GC will start to work, and the speed will definitely be quite slow. Here is an example that is not very appropriate:

String S1 = "abc"; 
For(int I = 0 ; I < 10000 ; I ++) // For 模拟程序的多次调用 
{ 
S1 + = "def"; 
S1 = "abc"; 
}
Copy after login

If this is the case, after the for loop is completed, if the objects in the memory have not been cleared by GC, there will be more than 20,000 objects in the memory. , an astonishing number, and if this is a system used by many people, this number is not very large, so everyone must be careful when using it.

If you use the StringBuffer class, the result will be different. Each result will operate on the StringBuffer object itself, instead of generating a new object and then changing the object reference. So in general we recommend using StringBuffer, especially when string objects change frequently. In some special cases, the string concatenation of String objects is actually interpreted by the JVM as the concatenation of StringBuffer objects, so in these cases the speed of String objects will not be slower than that of StringBuffer objects, and especially the following string objects are generated , String efficiency is much faster than StringBuffer:

String S1 = "This is only a" + " simple" + " test"; 
StringBuffer Sb = new StringBuilder("This is only a").append(" simple").append(" test");
Copy after login

You will be surprised to find that the speed of generating String S1 objects is simply too fast, and at this time, StringBuffer actually has no advantage at all in speed. . In fact, this is a trick of the JVM. In the eyes of the JVM, this

String S1 = "This is only a" + " simple" + "test"; 其实就是: String S1 = "This is only a simple test"; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: 
String S2 = "This is only a"; 
String S3 = " simple"; 
String S4 = " test"; 
String S1 = S2 +S3 + S4;
Copy after login

At this time, the JVM will do it in the original way, and the generation speed of S1 objects will not be as fast as before. After a while We can do a test to verify it.

From this we get the first step conclusion: In most cases StringBuffer > String

And how does StringBuilder compare with them? Let me give a brief introduction first. StringBuilder is a newly added class in JDK5.0. The difference between it and StringBuffer is as follows (source JavaWorld):

Java.lang.StringBuffer Thread-safe variable character sequence. A string buffer similar to String, but cannot be modified. String buffers can be used safely by multiple threads. These methods can be synchronized when necessary, so that all operations on any particular instance appear to occur in a serial order consistent with the order of method calls made by each thread involved.

Each string buffer has a certain capacity. As long as the length of the character sequence contained by the string buffer does not exceed this capacity, there is no need to allocate a new internal buffer array. This capacity is automatically increased if the internal buffer overflows. Starting with JDK 5.0, an equivalent class for single thread use has been added to this class, StringBuilder. The StringBuilder class should generally be used in preference to this class because it supports all the same operations but is faster because it does not perform synchronization.

But it is unsafe to use an instance of StringBuilder with multiple threads. If such synchronization is required, it is recommended to use StringBuffer.

I think everyone can understand the difference between them, so let’s make a general deduction below:

In most cases StringBuilder > StringBuffer

Therefore, according to the transfer theorem of this inequality: In most cases StringBuilder > StringBuffer > String

Now that there is such a derivation result, let’s do a test to verify it:

Test code show as below:

public class testssb { 

/** Creates a new instance of testssb */ 
final static int ttime = 10000;// 测试循环次数 
public testssb() { 
} 

public void test(String s){ 
long begin = System.currentTimeMillis(); 
for(int i=0;i<ttime;i++){ 
s += "add"; 
} 
long over = System.currentTimeMillis(); 
System.out.println(" 操作 "+s.getClass().getName()+" 类型使用的时间为: " + (over - begin) + " 毫秒 " ); 
} 

public void test(StringBuffer s){ 
long begin = System.currentTimeMillis(); 
for(int i=0;i<ttime;i++){ 
s.append("add"); 
} 
long over = System.currentTimeMillis(); 
System.out.println(" 操作 "+s.getClass().getName()+" 类型使用的时间为: " + (over - begin) + " 毫秒 " ); 
} 

public void test(StringBuilder s){ 
long begin = System.currentTimeMillis(); 
for(int i=0;i<ttime;i++){ 
s.append("add"); 
} 
long over = System.currentTimeMillis(); 
System.out.println(" 操作 "+s.getClass().getName()+" 类型使用的时间为: " + (over - begin) + " 毫秒 " ); 
} 

// 对 String 直接进行字符串拼接的测试 
public void test2(){ 
String s2 = "abadf"; 
long begin = System.currentTimeMillis(); 
for(int i=0;i<ttime;i++){ 
String s = s2 + s2 + s2 ; 
} 
long over = System.currentTimeMillis(); 
System.out.println(" 操作字符串对象引用相加类型使用的时间为: " + (over - begin) + " 毫秒 " ); 
} 

public void test3(){ 
long begin = System.currentTimeMillis(); 
for(int i=0;i<ttime;i++){ 
String s = "abadf" + "abadf" + "abadf" ; 
} 
long over = System.currentTimeMillis(); 
System.out.println(" 操作字符串相加使用的时间为: "+ (over - begin) + " 毫秒 " ); 
} 

public static void main(String[] args){ 
String s1 ="abc"; 
StringBuffer sb1 = new StringBuffer("abc"); 
StringBuilder sb2 = new StringBuilder("abc"); 

testssb t = new testssb(); 
t.test(s1); 
t.test(sb1); 
t.test(sb2); 
t.test2(); 
t.test3(); 
} 
}
Copy after login

以上代码在 NetBeans 5.0 IDE/JDK1.6 上编译通过,循环次数 ttime 为 10000 次的测试结果如下: 
操作 java.lang.String 类型使用的时间为: 4392 毫秒 
操作 java.lang.StringBuffer 类型使用的时间为: 0 毫秒 
操作 java.lang.StringBuilder 类型使用的时间为: 0 毫秒 
操作字符串对象引用相加类型使用的时间为: 15 毫秒 
操作字符串相加使用的时间为: 0 毫秒 

好像还看不出 StringBuffer 和 StringBuilder 的区别,把 ttime 加到 30000 次看看: 
操作 java.lang.String 类型使用的时间为: 53444 毫秒 
操作 java.lang.StringBuffer 类型使用的时间为: 15 毫秒 
操作 java.lang.StringBuilder 类型使用的时间为: 15 毫秒 
操作字符串对象引用相加类型使用的时间为: 31 毫秒 
操作字符串相加使用的时间为: 0 毫秒 

StringBuffer 和 StringBuilder 的性能上还是没有太大的差异,再加大到 100000 看看,这里就不加入对 String 类型的测试了,因为对 String 类型这么大数据量的测试会很慢滴…… 
操作 java.lang.StringBuffer 类型使用的时间为: 31 毫秒 
操作 java.lang.StringBuilder 类型使用的时间为: 16 毫秒 

能看出差别了,但其中有多次的测试结果居然是 StringBuffer 比 StringBuilder 快,再加大一些到 1000000 看看(应该不会当机吧?): 
操作 java.lang.StringBuffer 类型使用的时间为: 265 毫秒 
操作 java.lang.StringBuilder 类型使用的时间为: 219 毫秒 

有些少区别了,而且结果很稳定,再大点看看, ttime = 5000000 : 

······ Exception in thread "main" java.lang.OutOfMemoryError: Java heap space ······ 

呵呵,算了,不去测试了,基本来说都是在性能上都是 StringBuilder > StringBuffer > String 的了。

更多Java之String、StringBuffer、StringBuilder的区别分析相关文章请关注PHP中文网!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template