StringBuffer与StringBuilder
java.lang.StringBuffer
代表可变的字符序列,JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。
不同于String
,StringBuffer
类的对象必须使用构造器生成,有3种构造器:
StringBuffer()
:初始capacity
为16的字符串缓冲区StringBuffer(int capacity)
:构造指定容量的字符串缓冲区StringBuffer(String str)
:将内容初始化为指定字符串内容,此时的capacity=str.length() + 16
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
// AbstractStringBuilder.java
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
源码初探
StringBuffer
继承AbstractStringBuilder
抽象类
通过char[] value
存放字符序列,它没有声明为final
,则是可变的,count
表示已使用的字符数,即有效字符的个数,而不是value
的容量。
常用方法
StringBuffer append(xxx)
:提供了多种append()
方法,用于进行字符串拼接
// StringBuffer.java
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
// AbstractStringBuilder.java
public AbstractStringBuilder append(String str) {
// 处理空字符串的情况
if (str == null)
return appendNull();
int len = str.length();
// 先确认value的容量是否足够容纳新增的str
ensureCapacityInternal(count + len);
// 将str的内容拼接到value,从count位置开始
str.getChars(0, len, value, count);
// 更新有效字符个数
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// 新增字符串后的长度 > 原value的长度
// 则需要更新value:重新构造一个长度为minimumCapacity的char[]数组(进行扩容),然后将原有value的内容复制过来,再将新的数组赋值给value
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value, newCapacity(minimumCapacity));
}
}
private int newCapacity(int minCapacity) {
// 扩容方法:原value.length * 2 + 2
int newCapacity = (value.length << 1) + 2;
// 扩容后的长度仍然无法容纳新字符序列
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
// 需要处理溢出等特殊情况
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
StringBuffer delete(int start, int end)
:删除指定位置的内容StringBuffer replace(int start, int end, String str)
:把[start, end)位置的内容替换为strStringBuffer insert(int offset, xxx)
:在指定位置插入xxxStringBuffer reverse()
:逆序当前字符序列
当
append()
和isnert()
时,如果原有的value数组长度不够,会进行扩容。以上方法支持链式调用。
int indexOf(String str)
String substring(int start, int end)
int length()
注意这里返回的不是capacity
,而是**count
,即实际字符串内容的长度**char charAt(int index)
void setCharAt(int index, char ch)
java.lang.StringBuilder
和StringBuffer
非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样,区别在于它是线程不安全的,效率更高。
对比
- String(JDK 1.0):不可变字符序列
- StringBuffer(JDK 1.0):可变字符序列,效率低,线程安全
- StringBuilder(JDK 5.0):可变字符序列,效率高,线程不安全