StringBuffer 和 StringBuilder
Introduction
In most cases, faster than StringBuffer String fast; faster than StringBuffer StringBuilder; StringBuffer and StringBuilder are subclasses of AbstractStringBuilder, except that most of them have synchronized StringBuffer methods modified.
Source resolve
AbstractStringBuilder
Variables and Constructor
/**
* 用来存储字符的数组
* The value is used for character storage.
*/
char[] value;
/**
* 字符个数
* The count is the number of characters used.
*/
int count;
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
/**
* 在构造方法中指定字符数组的长度
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
Expansion
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > 0)
ensureCapacityInternal(minimumCapacity);
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
The method of expansion by the ultimate newCapacity()
implementation, a first capacity left (i.e., 2-fold expansion) while adding 2, if any case smaller than specified, then the capacity will be set minimumCapacity
. It is then determined whether the overflow, through hugeCapacity
implementation, if the overflow (greater than length Integer.MAX_VALUE
), then throw error ( OutOfMemoryError
); otherwise, according to minCapacity
and Integer.MAX_VALUE - 8
the magnitude of comparison determination array capacity max(minCapacity, Integer.MAX_VALUE - 8)
. Finally, the value
value of the copy, this step is clearly the most time-consuming operation.
append () method
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
append()
Is the most commonly used method, it has many forms of overloading. The above is the most commonly used, for appending the string. If str
Shi null
, the direct call
appendNull()
method. This method is the direct additional 'n'
, 'u'
, 'l'
, 'l'
several characters, as follows:
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
If not null
, you first need to determine whether the array capacity is sufficient, it is not required expansion (expansion of the expansion method is to call the above analysis);
then call String
a getChars()
method to str
append to value
the end;
finally returns the object itself, it append()
can continuously invoke (a kind of similar to the chain programmed).
Think
- Why every time expansion is the expansion to twice the original?
Personally I feel that in order to avoid the cost of expansion is often caused by consumption. - Why do plus 2?
Personally I thought what a good explanation, that may be becauseJava
developers think ourappend
time data center often add a separator, the separator in justJava
exactly occupies two bytes. Do not know the right analysis, there are other opinions bigwigs can issue
be discussed in.
Method comparison and StringBuffer StringBuilder
By looking at the source code analysis found both to inherit AbstractStringBuilder
. And StringBuffer
the reason why is thread-safe, because rewrite AbstractStringBuilder
time method preceded by a synchronzied
modification of these methods; and StringBuilder
rewriting, when just directly call the parent class method, do not do other operations.
In fact discovered by reading the source code StringBuilder
and StringBuffer
the relationship between the similar HashMap
and HashTable
the relationship between.