定义:

从jdk1.5开始提供的新的封装字符串的类,StringBuilder,其字符串拼接操作的效率远远高于 String。

Java里面提供了String,StringBuffer和StringBuilder三个类来封装字符串

简介:

我们知道字符串其实就是由若干个字符线性排列而成的,可以理解为字符数组Array,那么既然是数组实现的,那就需要考虑到数组的特性,数组在内存中是一块连续的地址空间块,即在定义数组的时候需要指定数组的大小

换言之, 数组就分为可变数组和不可变数组。可变数组能够动态插入和删除,而不可变数组一旦分配好空间后则不能进行动态插入或删除操作。

在实际的字符串应用场景中,涉及到多种操作,比如字符串的插入,删除,修改,拼接,查询,替换...

String:

不可变类,属性value为不可变数组,即String初始化构造器没有初始容量为16的概念,你定义多少,String中字符数组的长度就是多少,不存在字符数组扩容一说。看下源码:

2

3

final修饰的String 类,以及final修饰的char[] value,表示String类不可被继承,且value只能被初始化一次。这里的value变量其实就是存储了String字符串中的所有字符。

那既然String,不可变。我们再看下它的截取方法subString()实现

4

这里可以看到,在substring方法中,如果传入的参数为0,就返回自身原对象,否则就是重新创建一个新的对象。

5

6

类似的我们可以看到,String类的concat方法,replace方法,都是内部重新生成一个String对象的。

这也就是为什么我们如果采用String对象频繁的进行拼接,截取,替换操作效率很低下的原因。

下面再看下StringBuilder对象的源码,分析为何其在做字符串的拼接,截取,替换方面效率远远高于String

StringBuilder:

内部可变数组,存在初始化StringBuilder对象中字符数组容量为16,存在扩容。

7

StringBuilder类继承AbstractStringBuilder抽象类,其中StringBuilder的大部分方法都是直接调用的父类的实现。

首先看下StringBuilder的构造方法

8

1:空参数的构造方法

9

10

2:自定义初始容量-构造函数

11

3:以字符串String 作为参数的构造

12

在参数Str 数组长度的基础上再增加16个字符长度,作为StringBuilder实例的初始数组容量,并将str字符串 append到StringBuilder的数组中。

13

具体看下父类AbstractStringBuilder的append方法

14

1:首先判断append的参数是否为null,如果为null的话,这里也是可以append进去的

15

其中ensureCapacityInternal方法是确保这次append 的时候StringBuilder的内部数组容量是满足的,即这次要append的null字符长度为4,加上之前内部数组中已有的字符位数c之后作为参数执行。

16

2:如果不为null的话,就获取这次需要append的str的字符长度。紧接着执行是否需要扩容的方法

3:重点看下append方法的关键:String的 getChars方法(从str的0位开始,到str的长度,当前StringBuilder对象的字符数组,当前数组已有的字符长度)

17

18

其实是调用了System的arraycopy方法 参数如下:

value为str的内部不可变字符数组,

srcBegin为从str 字符串数组的0下标开始,

srcEnd为str字符串数组的长度,

dst为StringBuilder对象的内部可变字符数组,

dstBegin则为StringBuilder对象中已有的字符长度(char[] 已有的元素长度)

即整个StringBuilder的append方法,本质上是调用System的native方法,直接将String 类型的str字符串中的字符数组,拷贝到了StringBuilder的字符数组中

19

toString():

最后说下StringBuilder的toString方法,

这里的toString方法直接new 一个String对象,将StringBuilder对象的value进行一个拷贝,重新生成一个对象,不共享之前StringBuilder的char[]

以上就是StringBuilder的拼接字符串的原理分析,可以发现没有像String一样去重新new 对象,所以在频繁的拼接字符上,StringBuilder的效率远远高于String类。

StringBuffer:

线程安全的高效字符串操作类,看下源码:

19

类图和StringBuilder一样,不多说

构造函数:

20

和StringBuilder一样,也不用多说,重点看下其append方法:

21

可以看到这里就是在append方法上加了同步锁,来实现多线程下的线程安全。其他的和StringBuilder一致。

这里比StringBuilder多了一个参数

22

这里的作用简单介绍一下,就是去缓存toString的

可以看下StringBuffer的toString方法

23

这里的作用就是如果StringBuffer对象此时存在toStringCache,在多次调用其toString方法时,其new出来的String对象是会共享同一个char[] 内存的,达到共享的目的。但是StringBuffer只要做了修改,其toStringCache属性值都会置null处理。这也是StringBuffer和StringBuilder的一个区别点。

总结:

String 类不可变,内部维护的char[] 数组长度不可变,为final修饰,String类也是final修饰,不存在扩容。字符串拼接,截取,都会生成一个新的对象。频繁操作字符串效率低下,因为每次都会生成新的对象。

StringBuilder 类内部维护可变长度char[] , 初始化数组容量为16,存在扩容, 其append拼接字符串方法内部调用System的native方法,进行数组的拷贝,不会重新生成新的StringBuilder对象。非线程安全的字符串操作类, 其每次调用 toString方法而重新生成的String对象,不会共享StringBuilder对象内部的char[],会进行一次char[]的copy操作。

StringBuffer 类内部维护可变长度char[], 基本上与StringBuilder一致,但其为线程安全的字符串操作类,大部分方法都采用了Synchronized关键字修改,以此来实现在多线程下的操作字符串的安全性。其toString方法而重新生成的String对象,会共享StringBuffer对象中的toStringCache属性(char[]),但是每次的StringBuffer对象修改,都会置null该属性值。

java stringbuffer原理_String,StringBuilder,StringBuffer 实现原理解析相关推荐

  1. Java String,StringBuilder和StringBuffer的区别 StringBuilder StringBuffer String

    可以证明,字符串操作是计算机程序设计中最常见的行为. String:不可变的对象,对String对象进行改变的时候其实都等同于生成了一个新的String对象,然后将引用指向新的String对象,原St ...

  2. 举例说明string类和stringbuffer类的区别_String,StringBuilder,StringBuffer的区别

    在JAVA中字符串的表示有三种方式 String StringBuilder StringBuffer . 关于String 需要注意两点: 1.String是不可变的字符串,它的底层是一个用fina ...

  3. java字符串相加_String字符串相加的原理

    **因为String是非常常用的类, jvm对其进行了优化, jdk7之前jvm维护了很多的字符串常量在方法去的常量池中, jdk后常量池迁移到了堆中 ** 方法区是一个运行时JVM管理的内存区域,是 ...

  4. 2.Java中String,StringBuilder以及StringBuffer的关系与区别

    String     StringBuffer     StringBuilder String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量 ...

  5. 探秘Java中String、StringBuilder以及StringBuffer

    相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它 ...

  6. [JAVA基础类库] String类 ○ StringBuffer类 ○ StringBuilder类

    引言 字符串就是一连串的字符序列,Java提供了String.StringBuffer和StringBuilder三个类来封装对字符串,并提供了系列方法来操作字符串对象. String类是不可变类的: ...

  7. Java中string拼接,StringBuilder,StringBuffer和+

    Java中string拼接,StringBuilder,StringBuffer和+,到底哪个更合适? StringBuilder线程不安全,效率较线程安全的StringBuffer高.jdk1.5之 ...

  8. Java 字符串拼接 StringBuilder() StringBuffer

            字符串拼接 普通方式 public class StringDemo2 {public static void main(String[] args) {// 表示获取从1970-01 ...

  9. 【JAVA SE】第十章 String类、StringBuffer类和StringBuilder类

    第十章 String类.StringBuffer类和StringBuilder类 文章目录 第十章 String类.StringBuffer类和StringBuilder类 一.String类 1.创 ...

  10. 【Java】Java中String、StringBuilder、StringBuffer三者的区别

    这三个类之间的区别主要是在两个方面(运行速度和线程安全)这两方面. 1. 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:  StringBuilder >StringBuffer & ...

最新文章

  1. java建立_利用Java创建Windows服务
  2. 深圳农村商业银行转账显示服务器无响应,深圳农村商业银行
  3. MySQL explain 命令
  4. PHP __FILE__
  5. mysql批量插入数据,一次插入多少行数据效率最高
  6. 【计算机网络】Internet原理与技术3 — 端口及套接字、用户数据报协议UDP、传输控制协议TCP
  7. 在markdown中通过html语法实现表格中的有序列表和无需列表
  8. pcie总线连接两台电脑_基于PCIE总线多主互连系统的设计与实现
  9. stl变易算法(一)
  10. COSCon'19 开源治理论坛——技术之外,那些更重要的事
  11. 蚂蚁课堂视频笔记思维导图-4期 七、Docker
  12. 【TLSR825x】windows下开发环境搭建,固件烧录方法
  13. 免杀Payload生成工具Veil的下载与使用
  14. 计算机出现假桌面怎么解决办法,Win10系统下“AppHangXProcB1”导致桌面频繁假死如何解决?...
  15. 利用阿里云虚拟机作为跳板机实现内网穿透
  16. LDO + 稳压管的扩压电路试用笔记
  17. opencv 打开网络摄像头
  18. UN Comtrade(联合国商品贸易统计数据库)数据爬取Python代码——使用动态IP
  19. Windows10关闭指定端口号命令
  20. ipv6默认网关怎么打开。有偿。

热门文章

  1. 3.2.2 请求分页管理方式
  2. Spring boot显示登录用户
  3. Servlet映射路径中的通配符
  4. python爬携程_python爬虫-携程-eleven参数
  5. typescript ajax,TypeScript的应用方式
  6. 硬核!一套基于SpringBoot + Vue 的开源物联网智能家居系统!
  7. 太火了!MyBatis Plus 为啥这么牛?
  8. 记一次使用 Lombok 翻车造成的事故!
  9. 面试中又被问到Redis如何实现抢购,赶快代码实现一波吧!
  10. java解压obb_Bundle包转apk(.obb格式转.apk)