您的位置:首页 > 编程语言 > Java开发

字符串拼接多种实现方式及性能详解

2018-01-09 15:46 525 查看
java中字符串拼接有多种方式。但是为了搞清楚它们之间的区别,我做了以下的实验。

一、使用“+”符号拼接

“+”号拼接是第一时间最能想到的方式。但是它的性能却不如人意,下面是我实验的代码:
public static void a(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string = string + i;
}
long endTime = new Date().getTime();
System.out.println("“+”号花费时间:"+(endTime - starTime));
}
这种方式花费的时间在6800毫秒左右。(由于机器性能不同,执行的时间也会有所差异。为了保证实验结果的正确性,请都在同一台机器上运行。)

二、使用“+=”符号拼接

在python语言中“+=”符号与“+”符号拼接存在实质的区别。所以,我也试着在

java中实验看看:
public static void b(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string += i;
}
long endTime = new Date().getTime();
System.out.println("“+=”号花费时间:"+(endTime - starTime));<
4000
br />}
这种方式花费的时间大致与“+”号拼接相同,也在6800毫秒左右。如果有对python比较熟悉的,可以分别运行看一下。

三、使用concat方法拼接

直接看代码:
public static void e(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string = string.concat(String.valueOf(i));
}
long endTime = new Date().getTime();
System.out.println("concat花费时间:"+(endTime - starTime));
}
这种方式花费的时间在2400毫秒左右。

四、使用StringBuffer方式拼接

为了保证足够的严谨,我在这个实验中同样新建了一个String类型的对象。下面

是实验代码:
public static void c(){
long starTime = new Date().getTime();
String string = new String();
StringBuffer stringb = new StringBuffer();
for(int i=0;i<50000;i++){
stringb = stringb.append(i);
}
string = string + stringb;
long endTime = new Date().getTime();
System.out.println("StringBuffer花费时间:"+(endTime - starTime));
}
这种方式花费的时间在37毫秒左右。

五、使用StringBuilder方式拼接

实验代码:
public static void d(){
long starTime = new Date().getTime();
String string = new String();
StringBuilder stringb = new StringBuilder();
for(int i=0;i<50000;i++){
stringb = stringb.append(i);
}
string = string + stringb;
long endTime = new Date().getTime();
System.out.println("StringBuilder花费时间:"+(endTime - starTime));
}
这种方式花费的时间也在37毫秒左右。由于5万次拼接对于StringBuffer和StringBuilder来说没什么区别,所以我把执行次数增加到了500万次。在500万次的执行中StringBuffer花费大约627毫秒;StringBuilder花费大约418毫秒。

“+”号拼接与concat方法拼接的区别

首先来看JDK中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);
    }
通过上面的源码我们可以发现,concat方法通过确认两个字符串中字符的个数新建一个字符数组。
    void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }
最后再通过构造函数创建一个新的String对象。

“+”号方式拼接博主查阅了很多资料。通过反编译class文件最后发现“+”号拼接其实是用StringBuilder来实现的。那么又带来了一个疑问,如果是使用StringBuilder方式实现的话,那为什么它的性能如此之差呢?

带着这个疑问我把“+”号底层实现代码与第一次实验中的“+”号进行了替换:
public static void a(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
StringBuilder sb = new StringBuilder();
sb.append(string).append(String.valueOf(i));
string = sb.toString();
}
long endTime = new Date().getTime();
System.out.println("“+”号底层替换花费时间:"+(endTime - starTime));
}
这段代码花费了9000毫秒左右。而且在大量的拼接过程中会反复的创建StringBuilder对象。

思考一下,“+”号拼接在任何情况下性能都低于StringBuilder吗?

我就不向一件事分好多次说的人学习了。答案:当然不是。
String string = "Hua" + "PL";
在上面这种字符串拼接中“+”号的速度简直领人惊叹。同样我也进行了实验。由于他们的执行速度过快,我把执行次数依然调到了500万次。下面是实验的两段代码:
public static void a(){
long starTime = new Date().getTime();
for(int i=0;i<5000000;i++){
String string = "Hua" + "PL";
}
long endTime = new Date().getTime();
System.out.println("“+”号花费时间:"+(endTime - starTime));
}

public static void d(){
long starTime = new Date().getTime();
for(int i=0;i<5000000;i++){
StringBuilder string = new StringBuilder("Hua");
string = string.append("PL");
}
long endTime = new Date().getTime();
System.out.println("StringBuilder花费时间:"+(endTime - starTime));
}
这种方式的拼接,“+”号方式只用了10毫秒;而StringBuilder用了314毫秒。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息