java 字符串拼接的研究与优化

String 在java中是不可变的,每一个对String进行操做的方法实际上都是返回一个新的String对象,并使原来的String对象不可达。对String的链接常有下面几种方法,一种是使用‘+’符号,另外一种是使用StringBuilder,再就是String的concat方法。 java

(1) ‘+’: app

为了研究'+'的实现,咱们写如下测试代码: 工具

public static void main(String[] args) {
	String a="hell"+"o";   //code1
	String b="world";
	for(int i=0;i<4;i++) {
	   a+=b;             //code2
	}
}
把上面代码编译后再用jdk的反编译工具(javap)反编译下,获得以下代码:
public static void main(java.lang.String[]);
  Code:
   0:    ldc    #16; //String hello
   2:    astore_1
   3:    ldc    #18; //String world
   5:    astore_2
   6:    iconst_0
   7:    istore_3
   8:    goto    33
   11:    new    #20; //class java/lang/StringBuilder
   14:    dup
   15:    aload_1
   16:    invokestatic    #22; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   19:    invokespecial    #28; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   22:    aload_2
   23:    invokevirtual    #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   26:    invokevirtual    #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   29:    astore_1
   30:    iinc    3, 1
   33:    iload_3
   34:    iconst_4
   35:    if_icmplt    11
   38:    return
从code1能够获得“若是在‘+’左右没有变量的时候,‘+‘的结果是直接得出的。

从code2能够获得,若是在‘+’左右有变量的时候,会生成一个StringBuilder对象,而后调用其append方法。 测试

在一个拼接String的语句中,若是被拼接的String中有String对象,那这个语句会生成一个StringBuilder对象,而后调用其append方法. ui

注意源码中的循环,反编译后在代码中对应的是<line>8</line>到<line>35</line>,而建立StringBuilder对象被包含在了循环内,因此上面的代码会建立过多StringBuilder对象而影响效率。 this

(2) StringBuilder lua

下面咱们来分析下StringBuilder的append方法,其源码以下: code

public StringBuilder append(String str) {
	super.append(str);
        return this;
    }
super.append(str)以下:
public AbstractStringBuilder append(String str) {
	if (str == null) str = "null";
        int len = str.length();
	if (len == 0) return this;
	int newCount = count + len;
	if (newCount > value.length)
	    expandCapacity(newCount);//此方法拓展StringBuilder的容量至当前容量的2倍
	str.getChars(0, len, value, count);
	count = newCount;
	return this;
    }
经过分析源码咱们能够发现StringBuilder的效率是很高的(这也是java编译器默认采用StringBuilder的缘由),但要注意拓展容量的操做,因此适当设置初始容量是颇有必要的。

(3)String的concat方法 对象

其源码以下: ci

public String concat(String str) {
	int otherLen = str.length();
	if (otherLen == 0) {
	    return this;
	}
	char buf[] = new char[count + otherLen];
	getChars(0, count, buf, 0);
	str.getChars(0, otherLen, buf, count);
	return new String(0, count + otherLen, buf);
    }

这个方法的做用很简单,就是建立一个新String对象。

结论:

定义三个变量:String a="a",b="b",c="c";

1.对于简单拼接,如String d=a+b,建议使用concat方法:String d=a.concat(b);来减小生成没必要要的StringBuilder对象

2.对于二次以上拼接,如String d=a+b+c,使用这种方式就能够

3.对于涉及到循环的拼接,如:

String d="";
String e="";
for(int i=0;i<10;i++) {
   d+=a;//或d=d+a;
   e+=(a+b);//或e=e+a+b;
}

建议采用如下方式:

StringBuilder d = new StringBuilder(10)//设置初始容量以减小拓容操做
StringBuilder e = new StringBuilder(20);
for(int i=0;i<10;i++) {
  d.append(a);
  e.append(a).append(b);
}
#本文参考自《thinking in java》第四版Strings章节
相关文章
相关标签/搜索