你真的会使用字符串拼接吗?

2023-07-16 14:28:18 浏览数 (3)

一般我们拼接字符串的方式有三种:

  • 加号
  • concat方法
  • StringBuilder的append()方法
代码语言:javascript复制
 //加号
 str  = "xiaobear"
     //concat方法
 str = str.concat("xiaobear")

测试性能

分别对上面三种方式循环5w次

代码语言:javascript复制
public class StringTest {
 
     public static void main(String[] args) {
         doWithAdd();
         doWithConcat();
         doWithStringBuilder();
    }
 
     public static void doWithAdd(){
         StopWatch stopWatch = new StopWatch();
         String s = null;
         stopWatch.start("add");
         for (int i = 0; i < 50000; i  ) {
             s  = "xiaobear";
        }
         stopWatch.stop();
         System.out.println("add耗时:"   (stopWatch.getTotalTimeMillis())   "ms");
    }
 
     public static void doWithConcat(){
         StopWatch stopWatch = new StopWatch();
         String s = "1";
         stopWatch.start("concat");
         for (int i = 0; i < 50000; i  ) {
             s = s.concat("xiaobear") ;
        }
         stopWatch.stop();
         System.out.println("concat耗时:"   (stopWatch.getTotalTimeMillis())   "ms");
    }
 
     public static void doWithStringBuilder(){
         StopWatch stopWatch = new StopWatch();
         StringBuilder s = new StringBuilder("1");
         stopWatch.start("StringBuilder");
         for (int i = 0; i < 50000; i  ) {
             s.append("xiaobear");
        }
         stopWatch.stop();
         System.out.println("StringBuilder耗时:"   (stopWatch.getTotalTimeMillis())   "ms");
    }
 
 }
代码语言:javascript复制
add耗时:7320ms
concat耗时:2001ms
StringBuilder耗时:1ms

加号的执行时间为7320ms,concat方法的执行时间为2001ms,而StringBuilder几乎接近0,时间非常短;

说明在拼接字符串上,append()方法最快,concat 方法次之,加号最慢;

“ ” 方法拼接字符串

虽然编译器对子­符串的加号做了优化,它会使用StringBuilderd的append方法进行追加,按道理来说, 其执行时间也应该是 0 毫秒,最终是通过toString()转换为字符串的

示例中的“ ”拼接的代码与如下代码相同

代码语言:javascript复制
 str  = "xiaobear"
 
 str = new StringBuilder(str).append("xiaobear").toString();

它与StringBuilder的append()是不同的:

  • 每次循环都会创建一个StringBuilder对象
  • 拼接完成后,会调用toString()转换为字符串

所以耗时就消耗在这里了

concat方法拼接字符串

代码语言:javascript复制
 //源码
 public String concat(String str) {
     //如果拼接的字符串为0,则返回字符串本身
     if (str.isEmpty()) {
         return this;
    }
     //获取原字符数组的长度
     int len = value.length;
     //获取拼接字符串的长度
     int otherLen = str.length();
     //数组拷贝
     char buf[] = Arrays.copyOf(value, len   otherLen);
     //拼接字符串转化为字符数组,添加到buf
     str.getChars(buf, len);
     //返回一个新的字符串
     return new String(buf, true);
 }

整体看上去是一个数组拷贝,内存中处理的也是原子操作,速度很快,但是最后返回的,都会创建一个新的String对象,循环5w次,就创建了5w个String对象

append方法拼接字符串

代码语言:javascript复制
public AbstractStringBuilder append(String str) {
     //拼接字符串为空,返回空字符串
     if (str == null)
         return appendNull();
     //获取字符串长度
     int len = str.length();
     //加长,并进行数组拷贝
     ensureCapacityInternal(count   len);
     //字符串复制到目标数组
     str.getChars(0, len, value, count);
     //count长度增加
     count  = len;
     return this;
 }

append()方法都在做字符串数组处理,加长,数组拷贝,没有新建任何对象,所以速度是最快的!

三者的实现不同,性能也就不同,并不是我们一定要使用StringBuilder,对于简单的拼接,“ ”号更能简化代码,符合我们日常的使用习惯,阅读性也好一点;

在性能层面上,才去考虑使用concat()方法或append()方法;

0 人点赞