如果需要在循环中使用字符串的拼接,建议使用StringBuilder。
public class StringTest {
public static void main(String[] args){
String[] sb = new String[100000];
for(int i =0; i < 100000; i++){
sb[i] = "a";
}
testString1(sb);
testString2(sb);
}
public static void testString(){
String s = "abc" + "def" + "ghi";
}
public static void testString1(String[] fileds){
long startTime = System.currentTimeMillis();
String s = "";
for(int i = 0; i < fileds.length; i++){
s = s + fileds[i];
}
long endTime = System.currentTimeMillis();
System.out.println("string:"+ (endTime - startTime));
}
public static void testString2(String[] fields){
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < fields.length; i++){
sb.append(fields[i]);
}
long endTime = System.currentTimeMillis();
System.out.println("string:"+ (endTime - startTime));
}
输出:
string:2676
string:0
可以看到循环次数很大时,所需要的时间差别会非常大。
分析:
testString(),有限次的相加,使用String和StringBuilder是没有区别的,因为编译器会帮我们优化,这种字符串的相加操作,编译器会帮我们用StringBuilder来处理,使用javap反编译上面的代码,可以看到字符串的相加操作使用的是StringBuilder。
testString1(String[] fileds),编译器会在每次循环中都创建一个StringBuilder对象,相当于创建了10000个对象。
testString2(String[] fileds),只有一个StringBuilder对象
上面java文件反编译后如下:
javap -c StringTest
警告: 二进制文件StringTest包含String.StringTest
Compiled from "StringTest.java"
public class String.StringTest {
public String.StringTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // int 100000
2: anewarray #3 // class java/lang/String
5: astore_1
6: iconst_0
7: istore_2
8: iload_2
9: ldc #2 // int 100000
11: if_icmpge 25
14: aload_1
15: iload_2
16: ldc #4 // String a
18: aastore
19: iinc 2, 1
22: goto 8
25: aload_1
26: invokestatic #5 // Method testString1:([Ljava/lang/String;)V
29: aload_1
30: invokestatic #6 // Method testString2:([Ljava/lang/String;)V
33: return
public static void testString();
Code:
0: ldc #7 // String abcdefghi
2: astore_0
3: return
public static void testString1(java.lang.String[]);
Code:
0: invokestatic #8 // Method java/lang/System.currentTimeMillis:()J
3: lstore_1
4: ldc #9 // String
6: astore_3
7: iconst_0
8: istore 4
10: iload 4
12: aload_0
13: arraylength
14: if_icmpge 45
17: new #10 // class java/lang/StringBuilder
20: dup
21: invokespecial #11 // Method java/lang/StringBuilder."<init>":()V
24: aload_3
25: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: aload_0
29: iload 4
31: aaload
32: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
35: invokevirtual #13 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
38: astore_3
39: iinc 4, 1
42: goto 10
45: invokestatic #8 // Method java/lang/System.currentTimeMillis:()J
48: lstore 4
50: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream;
53: new #10 // class java/lang/StringBuilder
56: dup
57: invokespecial #11 // Method java/lang/StringBuilder."<init>":()V
60: ldc #15 // String string:
62: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
65: lload 4
67: lload_1
68: lsub
69: invokevirtual #16 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
72: invokevirtual #13 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
75: invokevirtual #17 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
78: return
public static void testString2(java.lang.String[]);
Code:
0: invokestatic #8 // Method java/lang/System.currentTimeMillis:()J
3: lstore_1
4: new #10 // class java/lang/StringBuilder
7: dup
8: invokespecial #11 // Method java/lang/StringBuilder."<init>":()V
11: astore_3
12: iconst_0
13: istore 4
15: iload 4
17: aload_0
18: arraylength
19: if_icmpge 37
22: aload_3
23: aload_0
24: iload 4
26: aaload
27: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
30: pop
31: iinc 4, 1
34: goto 15
37: invokestatic #8 // Method java/lang/System.currentTimeMillis:()J
40: lstore 4
42: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream;
45: new #10 // class java/lang/StringBuilder
48: dup
49: invokespecial #11 // Method java/lang/StringBuilder."<init>":()V
52: ldc #15 // String string:
54: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
57: lload 4
59: lload_1
60: lsub
61: invokevirtual #16 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
64: invokevirtual #13 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
67: invokevirtual #17 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: return