字符串拼接【面试题】

字符串拼接
方法比较
先来看一段代码:
public class Test {
public String method1() {
String ret = "";
for(int i=0;i<100000;i++){
ret=ret+"ok";
}
return ret;
}
public String method2() {
StringBuilder ret = new StringBuilder("");
for(int i=0;i<100000;i++){
ret.append("ok");
}
return ret.toString();
}
}
都知道 method1
的性能会比 method2
的性能差。那么理由是什么呢?
下面咱们来证明一下:
先编译代码,然后找到 Test.class
文件,然后执行命令
javap -verbose Test.class > tt.txt
然后打开 tt.txt
public java.lang.String method1();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: ldc #2 // String
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: sipush 1000
9: if_icmpge 38 // for循环
12: new #3 // class java/lang/StringBuilder
15: dup
16: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
19: aload_1
20: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: ldc #6 // String ok
25: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore_1
32: iinc 2, 1
35: goto 5
38: aload_1
39: areturn
public java.lang.String method2();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: new #3 // class java/lang/StringBuilder
3: dup
4: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V
7: astore_1
10: iconst_0
11: istore_2
12: iload_2
13: sipush 1000
16: if_icmpge 32 // for循环
19: aload_1
20: ldc #6 // String ok
22: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
25: pop
26: iinc 2, 1
29: goto 12
32: aload_1
33: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
36: areturn
LineNumberTable:
有上面看出 method2
只创建了一个 StringBuilder
对象。
而 method1
要创建 n
多个对象,而 method2
只需要创建一个对象,明显 method2
方式效率更高,推荐使用 method2(StringBuilder)
方式。
但如果在多线程环境下使用的话,推荐 StringBuffer
,因为 StringBuffer
是线程安全的。
StringBuffer 线程安全
StringBuffer
为什么线程安全?还不是因为在方法上加了一个 synchronized
修饰罢了。