JDK1.8源碼閱讀AbstractStringBuilder.class
AbstractStringBuilder是一個抽象類主要給子類實例化用的。它的主要繼承類有StringBuilder、StringBuffer。
代碼分析
抽象類
abstract class AbstractStringBuilder implements Appendable, CharSequence
內部有抽象方法,所以必須定義爲抽象類。@Override public abstract String toString();
變量
value存儲字符串,String底層也是一樣的儲存原理;count統計字符串長度,用於擴容。
char[] value;//存儲字符串,String底層也是一樣的儲存原理
int count;//統計字符串長度
無參構造函數
無參數構造函數用於子類的序列化,必需的
/**
* This no-arg constructor is necessary for serialization of subclasses.
* 無參數構造函數用於子類的序列化,必需的
*/
AbstractStringBuilder() {
}
方法
AbstractStringBuilder delete(int start, int end)
通過shift方法實現刪除操作,利用System.arraycopy來實現,把 end 後面的字符串複製到 start 位置,即相當於將中間的字符刪掉。
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)//異常檢測,避免熊孩子亂操作
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)//父親怎麼能大於孩子呢
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);//真正的幹活語句
count -= len;
}
return this;
}
AbstractStringBuilder insert(int offset, String str)
將原字符串從offset開始向移動len個長度,空出位置給新的str,再插入。
public AbstractStringBuilder insert(int offset, String str) {
if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset);
if (str == null)
str = "null";
int len = str.length();
ensureCapacityInternal(count + len);//確保足夠的容量
System.arraycopy(value, offset, value, offset + len, count - offset);//把 offset 後面的字符串複製到 offset+len 位置
str.getChars(value, offset);//將 str 放到 offset 位置,完成插入操作
count += len;//更新 count
return this;
}
String.class參考:
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
AbstractStringBuilder append(char c)
直接擴容,然後插入
@Override
public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
AbstractStringBuilder reverse()
時間複雜度O(n/2)
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; j--) {//num >> 1,相當於num除以2
int k = n - j;
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
}
測試reverse
package test;
public class reverse {
public static void main(String[] args) {
String a="dahouzi";
char[] value = a.toCharArray();
int count = a.length();
int n = count - 1;
for (int j = (n - 1) >> 1; j >= 0; j--) {
int k = n - j;
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
System.err.println(j+"---"+value[j]);
System.err.println(k+"---"+value[k]);
}
}
}
輸出:
2---u
4---h
1---z
5---a
0---i
6---d