字符串是 Java程序中最常用的数据结构之一,字符串连接又是经常使用到的。Java中有多种方式可以实现字符串的连接,如直接使用“+”连接两个String对象、StringBuilder的append()方法、String的concat()方法。今天,我们对比一下这几种方式的执行速度并分析下原因。
测试代码:
public class TestMain {
public static void main(String[] args){
String str1 = "str";
long start1 = System.currentTimeMillis();
for(int i=0;i<500000;i++){
str1 += "a";
}
long end1 = System.currentTimeMillis();
System.out.println("+的执行时间"+(end1 - start1)+"毫秒");
System.out.println();
String str2 = "str";
long start2 = System.currentTimeMillis();
for(int i=0;i<500000;i++){
str2.concat("a");
}
long end2 = System.currentTimeMillis();
System.out.println("concat的执行时间"+(end2 - start2)+"毫秒");
System.out.println();
StringBuilder str3 =new StringBuilder("str2:");
long start3 = System.currentTimeMillis();
for(int i=0;i<500000;i++){
str3.append("a");
}
long end3 = System.currentTimeMillis();
System.out.println("append的执行时间"+(end3 - start3)+"毫秒");
}
}
复制代码
执行结果:
从结果中很明显的看出,“+”拼接的效率要远远低于concat()方法和append()方法。为什么?“+”方法拼接字符串本质上是调用的StringBuilder的append()方法,在通过toString()方法返回字符串的,但是它是这样调用的 new StringBuilder().append(str).toString(),就是说我们执行了500000次“+”拼接,它就new了500000次StringBuilder对象并调用了500000次toString()方法转换为字符串,这是耗时的主要原因。
我们再看一下append()方法和concat()方法的源码实现:
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
//扩容
ensureCapacityInternal(count + len);
//调用System.arraycopy(),数组复制
sb.getChars(0, len, value, count);
count += len;
return this;
}
...
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
复制代码
在源码中不难发现,append()方法和concat()方法都是对字符数组加长然后复制,中间没有产生任何对象,所以效率会高。
尽管如此,也并不是所有情况都不用“+”方法,实际开发中,我们经常会有一两个字符串的拼接,这个时候还是建议使用“+”方法的,至少它比较符合人们的阅读习惯,代码也显得简洁。只是在进行较大量的字符串拼接时,还是尽量使用append()方法吧。
微信公众号:程序员Mark Chou