Heim > Java > javaLernprogramm > Analyse der Unterschiede zwischen Javas String, StringBuffer und StringBuilder

Analyse der Unterschiede zwischen Javas String, StringBuffer und StringBuilder

高洛峰
Freigeben: 2017-01-22 11:41:36
Original
1494 Leute haben es durchsucht

Ich glaube, dass jeder mit dem Unterschied zwischen String und StringBuffer vertraut ist, aber es wird geschätzt, dass viele Kameraden sich über die Funktionsweise dieser beiden Klassen noch nicht im Klaren sind. Heute werde ich dieses Konzept noch einmal für Sie überprüfen , eine neue Zeichenoperationsklasse, die in J2SE 5.0 eingeführt wurde – StringBuilder. Was sind also die Unterschiede zwischen diesem StringBuilder und StringBuffer und der String-Klasse, die wir zum ersten Mal kennengelernt haben? Welches sollten wir in verschiedenen Situationen verwenden? Ich möchte meine Ansichten zu diesen Kategorien mitteilen und hoffe auch, dass jeder seine Meinung äußern kann. Jeder hat Fehler gemacht und es ist eine gute Gelegenheit, etwas zu lernen.

Kurz gesagt, der Hauptleistungsunterschied zwischen dem String-Typ und dem StringBuffer-Typ besteht darin, dass String ein unveränderliches Objekt ist (warum? Fragen Sie die Designer von Java, warum ist String kein nativer Typ?) Daher jedes Mal Wenn Sie den String-Typ ändern, entspricht dies tatsächlich dem Generieren eines neuen String-Objekts und dem anschließenden Zeigen des Zeigers auf das neue String-Objekt. Daher ist es am besten, String nicht für Zeichenfolgen zu verwenden, deren Inhalt sich häufig ändert, da dies jedes Mal der Fall ist Dies wirkt sich negativ auf die Systemleistung aus, insbesondere wenn zu viele nicht referenzierte Objekte im Speicher vorhanden sind. Der GC der JVM beginnt zu arbeiten und die Geschwindigkeit ist definitiv recht langsam. Hier ist ein Beispiel, das nicht sehr passend ist:

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

Wenn dies der Fall ist, werden die Objekte im Speicher nach Abschluss der for-Schleife nicht vom GC bereinigt Mehr als 20.000 Objekte im Speicher Das ist eine erstaunliche Zahl, und wenn dies ein System ist, das von vielen Menschen verwendet wird, ist diese Zahl nicht sehr groß, daher muss jeder bei der Verwendung vorsichtig sein.

Wenn Sie die StringBuffer-Klasse verwenden, ist das Ergebnis unterschiedlich. Jedes Ergebnis wird auf das StringBuffer-Objekt selbst angewendet, anstatt ein neues Objekt zu generieren und dann die Objektreferenz zu ändern. Daher empfehlen wir im Allgemeinen die Verwendung von StringBuffer, insbesondere wenn sich String-Objekte häufig ändern. In einigen Sonderfällen wird die Zeichenfolgenverkettung von String-Objekten von der JVM tatsächlich als Verkettung von StringBuffer-Objekten interpretiert. Daher ist in diesen Fällen die Geschwindigkeit von String-Objekten nicht langsamer als die von StringBuffer-Objekten, insbesondere die folgenden Zeichenfolgenobjekte generiert, String-Effizienz ist viel schneller als StringBuffer:

String S1 = "This is only a" + " simple" + " test"; 
StringBuffer Sb = new StringBuilder("This is only a").append(" simple").append(" test");
Nach dem Login kopieren

Sie werden überrascht sein, dass die Geschwindigkeit beim Generieren von String-S1-Objekten einfach zu hoch ist, und zu diesem Zeitpunkt ist StringBuffer überhaupt nicht schnell . Dominieren. Tatsächlich handelt es sich hierbei um einen Trick der JVM.

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;
Nach dem Login kopieren

Zu diesem Zeitpunkt wird die JVM dies auf die ursprüngliche Weise tun, und die Generierungsgeschwindigkeit von S1-Objekten wird es tun Wenn es nicht mehr so ​​schnell ist wie zuvor, können wir es später durch einen Test überprüfen.

Daraus ergibt sich die erste Schlussfolgerung: In den meisten Fällen StringBuffer > String

Und wie schneidet StringBuilder im Vergleich dazu ab? Lassen Sie mich zunächst eine kurze Einführung geben. StringBuilder ist eine neu hinzugefügte Klasse in JDK5.0. Der Unterschied zwischen ihr und StringBuffer ist wie folgt (Quelle: JavaWorld):

Java.lang.StringBuffer ist eine threadsichere Variable Zeichenfolge. Ein String-Puffer ähnlich wie String, der jedoch nicht geändert werden kann. String-Puffer können sicher von mehreren Threads verwendet werden. Diese Methoden können bei Bedarf synchronisiert werden, sodass alle Vorgänge auf einer bestimmten Instanz scheinbar in einer seriellen Reihenfolge ausgeführt werden, die mit der Reihenfolge der Methodenaufrufe jedes beteiligten Threads übereinstimmt.

Jeder String-Puffer hat eine bestimmte Kapazität. Solange die Länge der im Zeichenfolgenpuffer enthaltenen Zeichenfolge diese Kapazität nicht überschreitet, besteht keine Notwendigkeit, ein neues internes Pufferarray zuzuweisen. Diese Kapazität wird automatisch erhöht, wenn der interne Puffer überläuft. Ab JDK 5.0 wurde dieser Klasse eine äquivalente Klasse für die Verwendung in einem einzelnen Thread hinzugefügt: StringBuilder. Im Allgemeinen sollte die StringBuilder-Klasse dieser Klasse vorgezogen werden, da sie dieselben Vorgänge unterstützt, aber schneller ist, da sie keine Synchronisierung durchführt.

Aber es ist unsicher, eine Instanz von StringBuilder mit mehreren Threads zu verwenden. Wenn eine solche Synchronisierung erforderlich ist, wird die Verwendung von StringBuffer empfohlen.

Ich denke, jeder kann den Unterschied zwischen ihnen verstehen, also lassen Sie uns unten eine allgemeine Schlussfolgerung ziehen:

In den meisten Fällen StringBuilder > StringBuffer

Daher gilt gemäß dem Übertragungssatz dieser Ungleichung: In den meisten Fällen StringBuilder > StringBuffer >

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(); 
} 
}
Nach dem Login kopieren

以上代码在 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中文网!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage