一般我们拼接字符串的方式有三种:
- 加号
- concat方法
- StringBuilder的append()方法
//加号
str = "xiaobear"
//concat方法
str = str.concat("xiaobear")
测试性能
代码语言:javascript复制分别对上面三种方式循环5w次
public class StringTest {
public static void main(String[] args) {
doWithAdd();
doWithConcat();
doWithStringBuilder();
}
public static void doWithAdd(){
StopWatch stopWatch = new StopWatch();
String s = null;
stopWatch.start("add");
for (int i = 0; i < 50000; i ) {
s = "xiaobear";
}
stopWatch.stop();
System.out.println("add耗时:" (stopWatch.getTotalTimeMillis()) "ms");
}
public static void doWithConcat(){
StopWatch stopWatch = new StopWatch();
String s = "1";
stopWatch.start("concat");
for (int i = 0; i < 50000; i ) {
s = s.concat("xiaobear") ;
}
stopWatch.stop();
System.out.println("concat耗时:" (stopWatch.getTotalTimeMillis()) "ms");
}
public static void doWithStringBuilder(){
StopWatch stopWatch = new StopWatch();
StringBuilder s = new StringBuilder("1");
stopWatch.start("StringBuilder");
for (int i = 0; i < 50000; i ) {
s.append("xiaobear");
}
stopWatch.stop();
System.out.println("StringBuilder耗时:" (stopWatch.getTotalTimeMillis()) "ms");
}
}
代码语言:javascript复制add耗时:7320ms
concat耗时:2001ms
StringBuilder耗时:1ms
加号的执行时间为7320ms,concat方法的执行时间为2001ms,而StringBuilder几乎接近0,时间非常短;
说明在拼接字符串上,append()方法最快,concat 方法次之,加号最慢;
“ ” 方法拼接字符串
虽然编译器对子符串的加号做了优化,它会使用StringBuilderd的append方法进行追加,按道理来说, 其执行时间也应该是 0 毫秒,最终是通过toString()转换为字符串的
示例中的“ ”拼接的代码与如下代码相同
代码语言:javascript复制 str = "xiaobear"
str = new StringBuilder(str).append("xiaobear").toString();
它与StringBuilder的append()是不同的:
- 每次循环都会创建一个StringBuilder对象
- 拼接完成后,会调用toString()转换为字符串
所以耗时就消耗在这里了
concat方法拼接字符串
代码语言:javascript复制 //源码
public String concat(String str) {
//如果拼接的字符串为0,则返回字符串本身
if (str.isEmpty()) {
return this;
}
//获取原字符数组的长度
int len = value.length;
//获取拼接字符串的长度
int otherLen = str.length();
//数组拷贝
char buf[] = Arrays.copyOf(value, len otherLen);
//拼接字符串转化为字符数组,添加到buf
str.getChars(buf, len);
//返回一个新的字符串
return new String(buf, true);
}
整体看上去是一个数组拷贝,内存中处理的也是原子操作,速度很快,但是最后返回的,都会创建一个新的String对象,循环5w次,就创建了5w个String对象
append方法拼接字符串
代码语言:javascript复制public AbstractStringBuilder append(String str) {
//拼接字符串为空,返回空字符串
if (str == null)
return appendNull();
//获取字符串长度
int len = str.length();
//加长,并进行数组拷贝
ensureCapacityInternal(count len);
//字符串复制到目标数组
str.getChars(0, len, value, count);
//count长度增加
count = len;
return this;
}
append()方法都在做字符串数组处理,加长,数组拷贝,没有新建任何对象,所以速度是最快的!
三者的实现不同,性能也就不同,并不是我们一定要使用StringBuilder,对于简单的拼接,“ ”号更能简化代码,符合我们日常的使用习惯,阅读性也好一点;
在性能层面上,才去考虑使用concat()方法或append()方法;