引言
StringBuffer和StringBuilder都是可变的字符字符序列,它们的主要的区别在于安全性,缓冲区&生成器,和性能三个方面。
安全性 | 缓冲区&生成器 | 性能 | |
---|---|---|---|
StringBuffer | 高 | 缓冲区 | 多线程高 |
StringBuilder | 低 | 生成器 | 单线程高 |
定义
StringBuffer
① 线程安全的可变字符序列。
② 一个类似于 String 的字符串缓冲区,但不能修改。
③ 虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
④ 可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
⑤ StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符添加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
StringBuilder
① 一个可变的字符序列。
② 此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
③ 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
④ 在 StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符添加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符。
构造方法
① 构造一个其中不带字符的字符缓冲区(StringBuffer)串生成器(StringBuilder),初始容量为 16 个字符。
/**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {
super(16);
}
② 构造一个其中不带字符的字符串缓冲区(StringBuffer)串生成器(StringBuilder),初始容量由 capacity 参数指定。
/**
* Constructs a string builder with no characters in it and an
* initial capacity specified by the {@code capacity} argument.
*
* @param capacity the initial capacity.
* @throws/@exception NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuilder(int capacity) {
super(capacity);
}
③ 构造一个字符串缓冲区(StringBuffer)串生成器(StringBuilder),并初始化为指定的字符串内容。
/**
* Constructs a string builder initialized to the contents of the
* specified string. The initial capacity of the string builder is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
④ 构造一个字符串缓冲区(StringBuffer)串生成器(StringBuilder),包含与指定的 CharSequence 相同的字符。
/**
* Constructs a string builder that contains the same characters
* as the specified {@code CharSequence}. The initial capacity of
* the string builder is {@code 16} plus the length of the
* {@code CharSequence} argument.
*
* @param seq the sequence to copy.
*/
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
区别
安全性
StringBuffer所有的公开的方法都由synchronized关键字修饰,保证了线程的安全性。
public synchronized int length()
public synchronized int capacity()
public synchronized void ensureCapacity(int minimumCapacity)
public synchronized void trimToSize()
public synchronized void setLength(int newLength)
public synchronized char charAt(int index)
public synchronized int codePointAt(int index)
public synchronized int codePointBefore(int index)
public synchronized int codePointCount(int beginIndex, int endIndex)
public synchronized int offsetByCodePoints(int index, int codePointOffset)
。。。
StringBuilder所有的公开的方法都是普通的方法,安全性较低。
public StringBuilder append(StringBuffer sb)
public StringBuilder append(CharSequence s)
public StringBuilder append(CharSequence s, int start, int end)
public StringBuilder append(char[] str)
public StringBuilder append(char[] str, int offset, int len)
public StringBuilder append(boolean b)
public StringBuilder append(char c)
public StringBuilder append(int i)
public StringBuilder append(long lng)
public StringBuilder append(float f)
。。。
缓冲区&生成器
StringBuffer中有一个缓冲区(toStringCache),缓存的是toString返回的最后一个值,当这个值被修改的时候清除。简单来讲把值进行了存储。
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
StringBuilder中则是生成器,即在调用toString方法的时候直接进行创建字符串,因此效率较慢。
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
性能
虽然StringBuffer中的缓冲区对性能有很大的提高,但是其synchronized特性使得它在面对多线程的时候效率低下,安全性极高。
相对而言,StringBuilder应用于多线程时无法保证安全,这一特性导致在开发中大多情况下都会使用StringBuffer,但在面对单线程的时候StringBuilder效率就比StringBuffer高很多。