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 的数组,并将原数组元素赋值过来。
public StringBuffer() { // 为了理解,这里对源码做了修改 return new byte[16]; }
- 当我们
new StringBuilder(String str)
调用有参构造器时,底层底层创建了一个我们传入字符串长度+16的一个数组- 一旦append超出了容量,就会扩容为原来的 2倍+2。新建一个容量为原来 2倍+2 的数组,并将原数组元素赋值过来。
public StringBuilder(String str) { // 为了理解这里对源码做了修改 return new byte[16 + str.length]; }
- 当我们
new StringBuilder(int number)
传入初始化容量时,底层创建了一个我们指定容量的数组。当确定数组容量时使用。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)这些方法支持方法链操作。原理: