(1)一个可爱的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全的),该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,他比StirngBuilder要快。
(2)在StringBulider上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。
我们查看StringBuilder的类图:
我们发现StringBuffer与StringBuild的父类完全一样。
StringBuilder(单线程)和StringBuffer(多线程)均代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样。
我们查看StringBuilder的源码如下所示:
我们查看数据保存到哪里,我们查看它所存储的父类:
仍然和StringBuffer一样,数据保存在value数组里面。
我们发现StringBuilder的方法里面没有synchronized,没有同步的。
package com.ypl.StringBuilder_;
public class StringBuild01 {
public static void main(String[] args) {
//1.StirngBuilder继承AbstractStringBuilder类
//2.实现了 Serializable,说明StringBuilder的对象可以串行化(该对象可以网络传输,可以保存到文件里)
//3.StringBuilder是final类,不能被继承
//4.StringBuilder对象字符序列仍然是存放在其父类AbstractStringBuilder的char [] value。
//因此,字符序列是堆中
//5.StringBuilder没有做互斥的处理,即没有synchronized关键字,因此在单线程的情况下使用StringBuilder.
StringBuilder stringBuilder = new StringBuilder();
}
}
String、StringBuffer和StringBuilder的比较
(1)StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也一样
(2)String:不可变字符序列,效率低,但是复用率(常量池里面有的内容可以被多个对象使用)高。
(3)StringBuffer:可变字符序列、效率较高(增删)、线程安全(synchorized同步代码块)
(4)StringBuilder:可变字符序列、效率最高、线程不安全
(5)如果从效率来看,StringBuilder的效率最高。StringBuilder>StringBuffer>String。
如果从安全来看,StringBuffer的最安全。
(5)String使用注意说明:
package com.ypl.StringBuilder_;
public class StringBuilder02 {
public static void main(String[] args) {
String s ="a"; //创建了一个字符串
s+="b";
/*实际原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b"(也就是”ab")。
如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能 =>
结论:如果我们对String做大量修改,不要使用String。
*/
}
}
我们来测试StringBuffer和StringBuilder和String的效率:
package com.ypl.StringBuilder_;
public class StringStringBuilderStringBuffer {
public static void main(String[] args) {
String text="";
long startTime=0;
long endTime=0;
StringBuffer buffer =new StringBuffer(text);
StringBuilder builder = new StringBuilder(text);
startTime = System.currentTimeMillis();
for (int i=0;i<200000;i++){ //StringBuffer拼接20000次
buffer.append(String.valueOf(i));
}
endTime=System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:+"+(endTime-startTime));
startTime=System.currentTimeMillis();
for (int i=0;i<200000;i++){ //StringBuilder拼接20000次
builder.append(String.valueOf(i));
}
endTime=System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:"+(endTime-startTime));
startTime=System.currentTimeMillis();
for (int i=0;i<200000;i++){ //String拼接20000次
text=text+i;
}
endTime=System.currentTimeMillis();
System.out.println("String的执行时间:"+(endTime-startTime));
}
}
我们运行之后如下所示:
我们发现StringBuilder的执行时间最短,然后是StringBuffer,最后是String。
使用的原则,结论:
1.如果字符串存在大量的修改操作,一般使用StringBuffer或StringBuilder
2. 如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder
3.如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
4.如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等
StringBuilder的方法使用和StringBuffer一样。