Java字符串拼接的几种方式和区别

在 java中,字符串的拼接方式你肯定不陌生,但是有注意过他们的区别吗?

常用方法

使用+拼接

使用+拼接是我们比较常用的做法

String s="hello";
String s1="world";
String s2=s+","+s1;

这种方式,有一些人会认为这是操作符重载,其实不然,Java中是不支持操作符重载的!其实这是Java的语法糖!

concat方法拼接

String s = "hello"; 
String s1 = "world"; 
String s2 = s.concat(",").concat(s1);

StringBuffer & StringBuilder

StringBuffer sb=new StringBuffer("hello");
StringBuffer sb1=new StringBuffer("world");
StringBuffer sb2=sb.append(",").append(sb1);

StringBuilder sb=new StringBuilder("hello");
StringBuilder sb1=new StringBuilder("world");
StringBuilder sb2=sb.append(",").append(sb1);

原理

“ +” 的原理

对以下代码进行反编译

String s="hello";
String s1="world";
String s2=s+","+s1;

得到如下代码

String s="hello";
String s1="world";
String s2=(new StringBuilder()).append(s).append(",").append(s1).toString();

由此我们可以看出,使用“+”进行字符拼接,实际上是使用了StringBuilder的append方法将字符串拼接起来,然后返回一个新的字符串!

concat的原理

//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方法的源代码我们可以看出,concat对于字符串的拼接是将原字符串与拼接的字符串存入了一个新的字符数组中,然后产生一个新的字符串来实现的!

StringBuffer & StringBuilder 的append方法原理

StringBuilder与String相似,都定义了一个字符数组

char[] value;

但是StringBuilder与String不同的是 字符数组value并没有用final修饰,这就意味着Stringbuilder的value是可变的!

另外, StringBuilder字符数组中不一定所有位置都已经被使用,它有一个实例变量,表示数组中已经使用的字符 个数,定义如下:

int count;

我们查看append方法的源代码

// StringBuffer
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
//StringBuilder
   @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

可以看出,StringBuffer的append方法使用了synchronized修饰,所以它是线程安全的!

StringBuilder与StringBuffer都继承了AbstractStringBuilder这个类。查看其append源代码如下:

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        // 判断是否需要扩容
        ensureCapacityInternal(count + len);
        // 将需要拼接的字符串放到字符数组中
        str.getChars(0, len, value, count);
        // 更新字符数组已用的数量
        count += len;
        return this;
    }

效率比较

long begin = System.currentTimeMillis();
 //这里是初始字符串定义 
for (int i = 0; i < 50000; i++) { 
//这里采用不通形式的字符串拼接方式
}
long end = System.currentTimeMillis(); 
System.out.println("cost:" + (end - begin));

测试结果

+cost:4990 
StringBuilder cost:15 
StringBuffer cost:16 
concat cost:1650 

结果分析

通过结果我们可以得出一下结论:

速度由大到小排列为:StringBuilder>StringBuffer>concat>"+"

1、StringBuffer比StringBuilder慢的原因是其加入了synchronized

2、“+”同样采用StringBuilder的append方法为什么效率会这么低呢?其实通过反编译后的代码我们不难看出来,使用“+”进行拼接会反复的进行 实例化的过程,花费了很多时间!

但是,在我们日常工作中还要强调的是:
1、如果不是在循环体中进行字符串拼接的话,直接使用+就好了。
2、如果在并发场景中进行字符串拼接的话,要使用 StringBuffer 来代替 StringBuilder。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LLLDa_&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值