Java字符串效率比较

@Test
    public void test() {
        String str = "a";
        long time = System.currentTimeMillis();
        for (int i = 0; i < 50000; i++) {
            str += "c";
        }
        System.out.println("加号所花费的时间:");
        System.out.println(System.currentTimeMillis()-time);
        String str2 = "a";
        time = System.currentTimeMillis();
        for (int i = 0; i < 50000; i++) {
            str2.concat("c");
        }
        System.out.println("cancat方法所花费的时间:");
        System.out.println(System.currentTimeMillis()-time);
        time = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder("a");
        for (int i = 0; i < 50000; i++) {
            stringBuilder.append("c");
        }
        String str3 = stringBuilder.toString();
        System.out.println("StringBuilder的append方法:");
        System.out.println(System.currentTimeMillis()-time);
    }

加号所花费的时间:
2391
cancat方法所花费的时间:
2
StringBuilder的append方法:
1
加号

虽然编译器对字符串的加号做了优化,它会使用StringBuilder的append方法进行追加,而它最终通过toString方法转换成String字符串,上例中“+”拼接的代码即如下:

str = new StringBuilder(str).append("xxxxx").toString();

它与纯粹地使用StringBuilder的append方法是不同的:
每趟循环都会创建一个StringBuilder对象
每次执行完毕后都会调用toString方法将其转化位字符串
所以,就耗费了更多的时间。

concat方法

concat源代码:

 public String concat(String str) {
        // 追加的字符串长度为0
        int otherLen = str.length();
        // 如果追加的字符串长度为0,则返回原字符串本身
        if (otherLen == 0) {
            return this;
        }
        // 获取原字符串的字符数组的长度
        int len = value.length;
        // 将原字符串的字符数组放到buf数组中
        char buf[] = Arrays.copyOf(value, len + otherLen);
        // 追加的字符串转化成字符数组,添加到buf中
        str.getChars(buf, len);
        // 产生一个新的字符串
        return new String(buf, true);
    }

整体是一个数组的拷贝,虽然在内存中是处理都是原子性操作,速度非常快,但是,最后的return语句创建一个新String对象,也就是每次concat操作都会创建一个新的String对象,这也是限制concat方法速度的原因。

append方法

append源代码:

public AbstractStringBuilder append(String str) {
        // 如果是null值,则把null作为字符串处理
        if (str == null)
            return appendNull();
        int len = str.length();
        // 追加后的字符数组长度是否超过当前值
        ensureCapacityInternal(count + len);
        // 字符串复制到目标数组
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
   private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);  // 加长,并作数组拷贝
    }

整个append方法都在做字符数组的处理,加长,拷贝等,这些都是基本的数据处理,整个方法内并没有生成对象。只是最后toString返回一个对象而已

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值