透彻分析String、StringBuilder和StringBuffer

StringBuilder与String的性能对比

在名企面试官面前,如果仅仅回答“String不可变、StringBuilder可变、String不可被继承”等等卖萌的答案,只能等着被pass!

StringBuilder.apend源码分析

先来看一段代码



输出结果

可以看出当进行大量的字符串拼接操作时,StringBuilder的append()方法比String的“+”快50倍以上!

我们来看一下它的源码调用过程:
首先会调用:StringBuilder append方法

然后调用父类的AbstractStringBuilder append

在该方法中有一个value属性值,是一个char类型的数组。

    if (newCount > value.length)
        expandCapacity(newCount);

当新的容量大于原来的容量时就进行扩容操作:


其中会调用Arrays.copyOf方法,把老的数组copy到新创建的数组(长度为原来的2n+2倍)中去
然后返回给原来的数组。然后把value引用指向新的数组。


扩容操作完成后返回AbstractStringBuilder append方法,执行str.getChars(0, len, value, count)方法,该方法的作用是把字符串拷贝到stringbuilder本身的char数组当中去,如果不需要扩容则直接执行这个方法。

综上可以得到调用StringBuilder调用append方法的流程为:

所以附加以下“面向对象”的回答,会更加出彩:

StringBuilder是抽象类AbstractStringBuilder的一个具体实现
StringBuilder与AbstractStringBuilder重载了不同的append()方法
所有的append()方法都会返回this,这样就实现了链式编程

其他细节:
执行流程

当数组容量不够的时候,会调用AbstractStringBuilder的expandCapacity()方法,将数组的容量扩大至原来的2n+2;
其中,expandCapacity()又调用了Arrays的copyOf()方法,目的是把原来数组的元素拷贝至新的数组。


String+"H"分析

概括一下整个过程:

  • 新开辟一个length+1的数组
  • 把原来的数组复制过来
  • 在数组尾部再复制一个H
  • 把原来value引用指向新的数组,旧数组会被GC回收器回收

同StringBuilder的append(),假设执行了65535次“+”,即:n=65535;那么,一共进行了多少次新对象、新数组的开辟,以及旧对象、旧数组的释放?
每次“+”,要new StringBuilder(),一共n次
每次“+”,要new char[str.length()+1],一共n次
故而,进行了2n次的开辟和释放。

String+ 和StringBuilder对比

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,516评论 0 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,754评论 18 399
  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,288评论 0 16
  • 你还不知道消息的话,可以去问问居委会,社区医院,街道计生办等单位,一定会告诉你,你居住的片区具体检查的时间安排的。...
    小轩成大轩阅读 896评论 0 0
  • 准备第三方插件 HtmlAgilityPack 在nuget中可以找到并下载 然后在项目中引用 代码步骤 从指定网...
    敲代码的小铁匠阅读 839评论 0 3