AbstractStringBuilder
abstract class AbstractStringBuilder implements Appendable, CharSequence{
...
}
1. inflate方法
inflate()
方法可以將當前的Latin1編碼的字串膨脹到16位,即UTF16編碼(Latin1編碼為8位)
/**
* If the coder is "isLatin1", this inflates the internal 8-bit storage
* to 16-bit <hi=0, low> pair storage.
*/
private void inflate() {
if (!isLatin1()) {
return;
}
byte[] buf = StringUTF16.newBytesFor(value.length);
StringLatin1.inflate(value, 0, buf, 0, count);
this.value = buf;
this.coder = UTF16;
}
2. ensureCapacity方法
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > 0) {
ensureCapacityInternal(minimumCapacity);
}
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
int oldCapacity = value.length >> coder;
if (minimumCapacity - oldCapacity > 0) {
// 拷貝過去
value = Arrays.copyOf(value, newCapacity(minimumCapacity) << coder);
}
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = value.length >> coder;
int newCapacity = (oldCapacity << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
ensureCapacity(miniCapacity)
方法保證當前容器的大小不小於miniCapacity
,如果小於的話就要進行擴容處理。擴容成下面兩者中的較大值。
- miniCapacity
- 2*oldCapacity
3. setCharAt方法
setCharAt()
方法可以將index處的字元設為ch
public void setCharAt(int index, char ch) {
checkIndex(index, count);
if (isLatin1() && StringLatin1.canEncode(ch)) {
value[index] = (byte)ch;
} else {
if (isLatin1()) {
inflate();
}
StringUTF16.putCharSB(value, index, ch);
}
}
4. append方法
append()
方法根據引數型別不同,在字串後面追加。
public AbstractStringBuilder append(CharSequence s) {
if (s == null) {
return appendNull();
}
if (s instanceof String) {
return this.append((String)s);
}
if (s instanceof AbstractStringBuilder) {
return this.append((AbstractStringBuilder)s);
}
return this.append(s, 0, s.length());
}
值得一提的是這個appendNull()
方法,當我們在試圖append一個空物件時,它居然選擇在builder串後面加上一個“null”,看下面的示例。
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("a");
String s = null;
stringBuilder.append(s);
System.out.println(stringBuilder.toString());
System.out.println(stringBuilder.toString().length());
}
輸出結果居然是
anull
5
也就是說,當append空物件時,會append一個“null”字串。
另外,當我們嘗試append一個boolean物件時,會append一個“true”串或者“false”串。
5. delete方法
delete
方法刪除builder中的一段
public AbstractStringBuilder delete(int start, int end) {
int count = this.count;
if (end > count) {
end = count;
}
checkRangeSIOOBE(start, end, count);
int len = end - start;
if (len > 0) {
shift(end, -len);
this.count = count - len;
}
return this;
}
類似地還有deleteCharAt
public AbstractStringBuilder deleteCharAt(int index) {
checkIndex(index, count);
shift(index + 1, -1);
count--;
return this;
}
6. reverse方法
reverse()
方法可以逆轉字元的順序。
public AbstractStringBuilder reverse() {
byte[] val = this.value;
int count = this.count;
int coder = this.coder;
int n = count - 1;
if (COMPACT_STRINGS && coder == LATIN1) {
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j;
byte cj = val[j];
val[j] = val[k];
val[k] = cj;
}
} else {
StringUTF16.reverse(val, count);
}
return this;
}
實際的方法就是雙指標靠攏+交換、
StringBuffer
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{
StringBuffer
類幾乎所有方法都是通過super
關鍵字呼叫AbstractStringBuilder
父類的方法。
StringBuffer
實現同步的方式就是給所有方法加上synchronized
關鍵字。
1. toStringCache變數
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient String toStringCache;
toStringCache
快取了toString()
方法的最後一次呼叫的值,在每次StringBuffer被修改前這個快取會清除。
toString()
方法中檢查如果有快取,就直接返回快取。這樣不用每次都處理toString()
的過程,而只在需要的時候處理。
public synchronized String toString() {
if (toStringCache == null) {
return toStringCache =
isLatin1() ? StringLatin1.newString(value, 0, count)
: StringUTF16.newString(value, 0, count);
}
return new String(toStringCache);
}
StringBuilder
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{
...
}
StringBuilder
類幾乎所有方法都是通過super
關鍵字呼叫AbstractStringBuilder
父類的方法。