【Java】StringBuffer、StringBuilder

2023-03-04 13:43:54 浏览数 (1)

1. StringBuffer、StringBuilder、String对比

  • String:不可变的字符序列;对于增删改效率最低
  • StringBuffer:可变的字符序列;jdk1.0声明;线程安全(使用了synchronized同步方法),所以效率较低,但都比String效率高
  • StringBuilder:可变的字符序列;jdk5.0声明;线程不安全,所以效率较高。大多场景不会涉及多线程,所以使用StringBuilder较多。

2. StringBuffer、StringBuilder可变特性分析(jkd1.8)

StringBuffer、StringBuilder底层逻辑一样,以StringBuilder来说:

当我们new StringBuilder()调用无参构造器时,底层创建了一个默认长度为16的数组。

  • 一旦append超出了容量,就会扩容为原来的 2倍 2。新建一个容量为原来 2倍 2 的数组,并将原数组元素赋值过来。
代码语言:javascript复制
public StringBuffer() {

  // 为了理解,这里对源码做了修改
  return new byte[16];

}

当我们new StringBuilder(String str)调用有参构造器时,底层底层创建了一个我们传入字符串长度 16的一个数组

  • 一旦append超出了容量,就会扩容为原来的 2倍 2。新建一个容量为原来 2倍 2 的数组,并将原数组元素赋值过来。
代码语言:javascript复制
  public StringBuilder(String str) {
  
  	 // 为了理解这里对源码做了修改
     return new byte[16   str.length];
    
  }

当我们new StringBuilder(int number)传入初始化容量时,底层创建了一个我们指定容量的数组。当确定数组容量时使用。

代码语言:javascript复制
 public StringBuilder(int capacity) {

	// 为了理解这里对源码做了修改
    return new byte[capacity]
}

3. 怎么选择?

  • 若需要频繁的对字符串进行增、删、改操作,建议使用StringBuffer、StringBuilder替换String
  • 若不涉及线程安全问题,使用StringBuilder,效率更高
  • 若确定了数组容量,使用new StringBuilder(int capacity)传入数组容量,性能能更好,因为可以避免底层多次扩容操作。

4. 常用API

增: (1)StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接 删: (2)StringBuffer delete(int start, int end):删除[start,end)之间字符 (3)StringBuffer deleteCharAt(int index):删除[index]位置字符 改: (4)StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str (5)void setCharAt(int index, char c):替换[index]位置字符 查: (6)char charAt(int index):查找指定index位置上的字符 插: (7)StringBuffer insert(int index, xx):在[index]位置插入xx 长度: (8)int length():返回存储的字符数据的长度 其他: (9)StringBuffer reverse():反转 (10)int indexOf(String str):在当前字符序列中查询str的第一次出现下标 (11)int indexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的第一次出现下标 (12)int lastIndexOf(String str):在当前字符序列中查询str的最后一次出现下标 (13)int lastIndexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的最后一次出现下标 (14)String substring(int start):截取当前字符序列[start,最后] (15)String substring(int start, int end):截取当前字符序列[start,end) (16)String toString():返回此序列中数据的字符串表示形式 (17)void setLength(int newLength) :设置当前字符序列长度为newLength

  • 当append和insert时,如果原来value数组长度不够,可扩容。
  • 如上(1)(2)(3)(4)(9)这些方法支持方法链操作。原理:

0 人点赞