1.String、StringBuffer/StringBuilder效率比较
对于较少字符串连接,使用String或者StringBuffer都行;但是对于大量字符串连接,效果差异就会变得非常明显,直接上代码:
<span style="font-size:18px;">package strings;
public class FastOrNot {
public static void main(String[] args) {
int N=10000;
String str="";
StringBuffer buffer=new StringBuffer();
StringBuilder builder=new StringBuilder();
long t1=System.currentTimeMillis();
for(int i=0;i<N;i++)
str=str+N;
long t2=System.currentTimeMillis();
for(int i=0;i<N;i++)
buffer.append(N);
long t3=System.currentTimeMillis();
for(int i=0;i<N;i++)
builder.append(N);
long t4=System.currentTimeMillis();
System.out.println(t2-t1);
System.out.println(t3-t2);
System.out.println(t4-t3);
}
}
</span>
打印出来的结果如下(单位ms):
663
2
0
效果差异在300倍以上。
原因在于,StringBuffer/StringBuilder是动态的,可以实现动态连接,用一个数组保存,每一次连接都是以字符形式放置与字符数组中。而String是不可变类,每一次都是创建一个新的对象。
StringBuffer继承AbstractStringBuffer。代码如下:
<span style="font-size:18px;"> public AbstractStringBuilder append(char str[]) {
int newCount = count + str.length;
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(str, 0, value, count, str.length);
count = newCount;
return this;
}</span>
通过代码研究发现类似于ArrayList的扩容机制。
2、StringBuffer/StringBuilder效率优化
看如下例子
<span style="font-size:18px;">
public class FastTry {
public static void main(String[] args) {
int N=100000;
StringBuffer buffer=new StringBuffer();
StringBuffer sizedBuffer=new StringBuffer(N);
long t1=System.currentTimeMillis();
for(int i=0;i<N;i++)
buffer.append(1);
long t2=System.currentTimeMillis();
for(int i=0;i<N;i++)
sizedBuffer.append(1);
long t3=System.currentTimeMillis();
System.out.println(t2-t1);
System.out.println(t3-t2);
}
}
</span>
打印出来的结果如下(单位ms):
7
4
说明若是预先知道大小,可以对进行初始容量大小设置,可以省略扩容时间。