当我们需要对字符串进行拼接时,我们首先想到的是最简单直观的String中的+=,但是,这种方式是不是最优的呢,如果是在次数很多的循环中呢?于是探究了java中字符串拼接的四种方法,比较了一下他们的利弊关系。
[b]下面是测试的代码:[/b][code="java"][/code]
public class StringJoint {
private int count = 50000;
public void direct(){
//直接拼接字符串
long start = System.currentTimeMillis();
String s = "";
for(int i=0;i<count;i++){
s =s+"a";
}
long end = System.currentTimeMillis();
System.out.println("拼接 "+count+" 次");
System.out.println("直接拼接用时:"+(end-start));
}
public void concat(){
//Concat拼接字符串
long start = System.currentTimeMillis();
String sConcat = "";
for(int i=0;i<count;i++){
sConcat =sConcat.concat("a");
}
long end = System.currentTimeMillis();
System.out.println("Concat用时:"+(end-start));
}
public void stringBurrer(){
//StringBuffer拼接字符串
long start = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0;i<count;i++){
sb.append("a");
}
long end = System.currentTimeMillis();
System.out.println("StringBuffer用时:"+(end-start));
}
public void stringBuilder(){
//StringBuilder拼接字符串
long start = System.currentTimeMillis();
StringBuilder sBulider = new StringBuilder();
for(int i=0;i<count;i++){
sBulider.append("a");
}
long end = System.currentTimeMillis();
System.out.println("StringBuilder用时:"+(end-start));
}
public static void main(String[] args) {
StringJoint sj =new StringJoint();
sj.direct();
sj.concat();
sj.stringBurrer();
sj.stringBuilder();
}
}
[b]运行结果:[/b]
拼接 50000 次
直接拼接用时:1575
Concat用时:788
StringBuffer用时:3
StringBuilder用时:2
以上结果单位是毫秒,从运行结果我们得到以下心得:
[b]1.[/b]String简单实用可观,String的+本来就是用StringBuilder或StringBuffer和他们的append()方法实现的,关键是不是同一个StringBuilder/StringBuffer。因为String是一个常类(初始化后就不会改变的类),在循环里用+=之类的方式来拼接字符串的问题就出在每轮循环里都new了一个StringBuilder/StringBuffer来做拼接,然后toString()完就抛弃了,等下轮循环进来又再new一个。
[b]2.[/b]concat是内部机制实现,比+的方式好了不少,但是由于额外的创建StringBuilder和
做append(str).append(str).toString()的操作,使得concat的性能会受到一些影响
[b]3.[/b]StringBuilder的出现就是用来替换StringBuffer的,StringBuilder的速度最快,但其有线程安全的问题,而且只有JDK5支持。
因此我们在做简单少量的字符串拼接时,可以使用String或者concat来实现,当需要大量的字符串拼接(特别是在循环中),且在不考虑线程安全和同步的情况下,使StringBuilder和StringBuffer的性能最优。
[b]下面是测试的代码:[/b][code="java"][/code]
public class StringJoint {
private int count = 50000;
public void direct(){
//直接拼接字符串
long start = System.currentTimeMillis();
String s = "";
for(int i=0;i<count;i++){
s =s+"a";
}
long end = System.currentTimeMillis();
System.out.println("拼接 "+count+" 次");
System.out.println("直接拼接用时:"+(end-start));
}
public void concat(){
//Concat拼接字符串
long start = System.currentTimeMillis();
String sConcat = "";
for(int i=0;i<count;i++){
sConcat =sConcat.concat("a");
}
long end = System.currentTimeMillis();
System.out.println("Concat用时:"+(end-start));
}
public void stringBurrer(){
//StringBuffer拼接字符串
long start = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0;i<count;i++){
sb.append("a");
}
long end = System.currentTimeMillis();
System.out.println("StringBuffer用时:"+(end-start));
}
public void stringBuilder(){
//StringBuilder拼接字符串
long start = System.currentTimeMillis();
StringBuilder sBulider = new StringBuilder();
for(int i=0;i<count;i++){
sBulider.append("a");
}
long end = System.currentTimeMillis();
System.out.println("StringBuilder用时:"+(end-start));
}
public static void main(String[] args) {
StringJoint sj =new StringJoint();
sj.direct();
sj.concat();
sj.stringBurrer();
sj.stringBuilder();
}
}
[b]运行结果:[/b]
拼接 50000 次
直接拼接用时:1575
Concat用时:788
StringBuffer用时:3
StringBuilder用时:2
以上结果单位是毫秒,从运行结果我们得到以下心得:
[b]1.[/b]String简单实用可观,String的+本来就是用StringBuilder或StringBuffer和他们的append()方法实现的,关键是不是同一个StringBuilder/StringBuffer。因为String是一个常类(初始化后就不会改变的类),在循环里用+=之类的方式来拼接字符串的问题就出在每轮循环里都new了一个StringBuilder/StringBuffer来做拼接,然后toString()完就抛弃了,等下轮循环进来又再new一个。
[b]2.[/b]concat是内部机制实现,比+的方式好了不少,但是由于额外的创建StringBuilder和
做append(str).append(str).toString()的操作,使得concat的性能会受到一些影响
[b]3.[/b]StringBuilder的出现就是用来替换StringBuffer的,StringBuilder的速度最快,但其有线程安全的问题,而且只有JDK5支持。
因此我们在做简单少量的字符串拼接时,可以使用String或者concat来实现,当需要大量的字符串拼接(特别是在循环中),且在不考虑线程安全和同步的情况下,使StringBuilder和StringBuffer的性能最优。