StringBuilder和StringBuffer

328 阅读31分钟

String、StringBuilder和StringBuffer的关系

为什么出现StringBuffer类和StringBuilder类

对字符串进行大量修改时,使用StringBuffer或StringBuilder。

String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。于是就有了StringBuffer类和StringBuilder类,通过直接操作String底层的char[]来对变化字符串进行处理。

StringBuilder和StringBuffer

StringBuffer和StringBuilder都继承了AbstractStringBuilder类。执行时基本是调用的父类的方发。于是其关键代码都在AbstractStringBuilder类。

StringBuilder 是线程安全的,方法前没有synchronized关键字。

StringBuffer  是县城不安全的,方法前基本都有synchronized关键字。

由于StringBuffer方法里有synchronized关键字,所以他的性能要低于StringBuilder。单线程的情况下,最好使用StringBuilder。多线程的情况下,就应该是用StringBuffer.

AbstractStringBuilder

初始化

初始化分为三种情况

  • 无参时默认容量为16

  • 当指定容量的值时,容量为指定的值,

  • 当传递的为字符串或CharSequence时,容量为参数的长度 + 16.

然后创建char数组  char[] value = new char[capacity];

扩容

  1. append的时候minimumCapacity(当前的长度 + 参数的长度 )大于当前value数组的长度时,扩容。

  2. 计算新数组的长度。一般情况为value数组的长度*2 +2.

  3. System.arraycopy()方法通过实现数组之间的复制来达到扩容的目的

追加

append(e)。实现也很好理解,之所以展示append(boolean b),是因为我觉得这种写法让我眼前一亮,需要记住并使用的代码风格。

反转

首先找到中间位置的元素,实现对称位置元素的互换

boolean isSurrogate(char ch)确定给定的char值是否为Unicode值

关于insert、delete、substring、indexOf方法

insert()和 delete()方法,最终都是通过System.arraycopy()方法实现的.

substring

 是通过String的构造函数new String()实现。

indexof方法,是通过使用String.indexOf()实现。

关于这些,在之前的 String源码赏析里都已经解释了。

结尾

今天看到一句话,所见即所得。 今日所见,终有一天会以各种方式呈现出来。

对象画的,我觉得挺好看的,和大家分享一下。