目录
前言
在开发过程中,String 类提供给我们很多好用的方法,对字符串的操作是最频繁的,在字符串拼接操作也有不同的用法,别再一股脑的用+号了
一、直接上测试结论
前提:使用Junit的@Test注解测试,循环拼接 10 万次
1、使用 String 的"+"拼接符(耗时28681毫秒
)
@Test
public void testString() {
long beginTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < 100000; i++) {
str = str +"***" + i;
}
long endTime = System.currentTimeMillis();
System.out.println("使用String的+号拼接符拼接10万次耗时 = " + (endTime-beginTime) + "毫秒");
}
2、使用String的concat()方法(耗时6924毫秒
)
@Test
public void testStringConcat() {
long beginTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < 100000; i++) {
str = str.concat("***" + i);
}
long endTime = System.currentTimeMillis();
System.out.println("使用String的concat()方法拼接10万次耗时 = " + (endTime-beginTime) + "毫秒");
}
3、使用StringBuffer(耗时13毫秒
)
@Test
public void testStringBuffer() {
long beginTime = System.currentTimeMillis();
StringBuffer str = new StringBuffer();
for (int i = 0; i < 100000; i++) {
str.append("***" + i);
}
long endTime = System.currentTimeMillis();
System.out.println("使用StringBuffer拼接10万次耗时 = " + (endTime-beginTime) + "毫秒");
}
4、使用StringBuilder (耗时11毫秒
)
@Test
public void testStringBuilder() {
long beginTime = System.currentTimeMillis();
StringBuilder str = new StringBuilder();
for (int i = 0; i < 100000; i++) {
str.append("***" + i);
}
long endTime = System.currentTimeMillis();
System.out.println("使用StringBuilder拼接10万次耗时 = " + (endTime-beginTime) + "毫秒");
}
二、不同方法的原理
1、String在使用"+"拼接符做字符串拼接时,在底层编译的时候其实都会new一个StringBuilder对象,所以会频繁创建对象,对内存的消耗比较大,也影响了执行的时间。
2、String的concat()方法在执行时其实就是拿将需要拼接的字符串转换成一个char[]数组,最后再转换成String对象。
3、StringBuffer在拼接字符串时只需要new一次StringBuffer对象,使用append()方法进行字符串的拼接。
4、StringBuilder 在拼接字符串时和StringBuffer一样,只需要new一次StringBuilder 对象,使用append()方法进行字符串的拼接。
三、使用场景
了解了他们在字符串拼接时的操作之后,在工作中还是要根据具体情况来使用。
1、较少次拼接:直接使用+号或者String的concat()方法就行了,需要注意在使用String.concat()方法时,拼接的类型必须是String类型,而+号不需要关心数据类型,直接拼接就完事了。
2、频繁拼接:
①在单线程环境下,使用StringBuffer、StringBuilder 几乎没有差别
②在多线程环境下,就要使用StringBuffer了,因为它的方法都是用synchronized修饰的,相当于加锁,毕竟在效率面前安全才是最重要的。
四、部分相关源码(有兴趣的可以研究研究)
1、String的concat()方法
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);
}
2、StringBuffer和StringBuilder用的append()方法其实是父类AbstractStringBuilder的append()方法
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}