今天呢,咋們要來研讀一段代碼,StringBuilder 和 Integer
要學好一個東西,咋們就必須深入研究,和它徹夜長談,把他剝一個白白淨淨,咋們才能看到他的真實面目
先來看看要和咋們徹夜長談的源代碼
import java.util.Arrays;
import part01.Object解析.Person;
public class StringBuildeDemo01 {
public static void main(String[] args) {
StringBuilder sb=new StringBuilder();
StringBuffer sb2=new StringBuffer();
String s=new String();
sb.append(10);
sb.append(new Person(30,"老李"));
sb.append("hahalalaxixi");
sb.append(true);
System.out.println(sb.toString());
//"10Person [age=30, name=老李]hahalalaxixitrue"
System.out.println(sb.capacity()); //指的是當前value的容量
System.out.println(sb.length()); //指的是當前value中有效字符的個數
// System.out.println(sb.charAt(100)); //字符串角標越界:StringIndexOutOfBoundsException
sb.deleteCharAt(0);
System.out.println(sb.toString());
sb.delete(0, 10);//[start,end)
System.out.println(sb.toString());
System.out.println(sb.indexOf("name"));
sb.insert(5, "lala");
System.out.println(sb.toString());
System.out.println(sb.reverse());
System.out.println("----------");
//toString()的新寫法
int[] arr={1,2,3,4,5,6,7,8,9,10};
System.out.println(arrayToString(arr));
System.out.println(Arrays.toString(arr));
}
private static String arrayToString(int[] arr) {
if(arr==null){
return "[]";
}
StringBuilder sb=new StringBuilder();
sb.append('[');
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
if(i==arr.length-1){
return sb.append(']').toString();
}
sb.append(',');
}
return null;
}
}
來,咋們看看這個源代碼,源代碼怎麼打開,長按Ctrl選擇你需要查看的
咋們可以得到
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence
這段代碼可以看到StringBuilder是由Final修飾的關鍵字,所以,我們可以知道這個這個類是不能被繼承的,
他繼承他的父類AbstractStringBuilder,而他的父類有兩個接口,我們看父類的源代碼可以看出來
abstract class AbstractStringBuilder implements Appendable, CharSequence
他的兩個接口分別是Appendable和CharSequence,他這裏將AbstractStringBuilder定義成抽象的,是爲了子類更好的繼承,他還實現了兩個接口;
接下來是:
char[] value; //該函數的作用是通過char數組,生成String字符串對象,接口中的參數是一個char數組
int count; //用於存儲字符串的
AbstractStringBuilder() { };//創建一個無參構造方法,子類沒有,父類必須有
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}//創建數組的容量是16
@Override
public int length() {
return count;
}//返回你當前字符串的長度,這個返回的是你輸入的字符串的長度
public int capacity() {
return value.length;
}//它返回的是Value數組的長度,也就是16
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));
}
}//這是輸入最小的輸入最小的字符串的長度,如果他的最小長度減去Value數組的長度>0,即證明他的長度,原先的數組不滿足,需要進行擴容。
int newCapacity = (value.length << 1) + 2;//這個<<是位移運算符,代表是將value數組的長度先轉換爲二進制數,然後向左移動一位,之後再換爲十進制,在+1;
public void trimToSize() {
if (count < value.length) {
value = Arrays.copyOf(value, count);
}
}//這就是先比較,如果你的新的數組長度比字符串的長度長的話,就將原數組全部複製進來;
比如,value是一個數組,count是8,他就複製8個數字;再然後他就會得到一些空餘的空間;
減少字符序列的使用空間,釋放掉沒有存儲數據的內存,也就是讓字符數組的實際長度和容量相等,此操作通過申請一個長度爲count的新空間來實現。
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength);
if (count < newLength) {
Arrays.fill(value, count, newLength, '\0');
}
count = newLength;
}//他這個Fill是在value數組中,第count個和第newlength個之間插入\0,並且將他的這個數組的空間填滿。
public char charAt(int index)//是獲取字符序列中指定index位置的字符,範圍是0-count,超出就拋;
public int codePointAt(int index)//他是返回指定index位置的字符
public int codePointBefore(int index)//他是返回指定index位置前的一個字符
public int codePointCount(int beginIndex, int endIndex)//)就是準確計算unicode字符的數量,而不是char的數量。
public int offsetByCodePoints(int index, int codePointOffset)//從給定的 index 處偏移 codePointOffset 個代碼點的索引
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)//將字符從字符串複製到目標字符數組srcBegin -- 字符串中要複製的第一個字符的索引。
srcEnd -- 字符串中要複製的最後一個字符之後的索引。
dst -- 目標數組。
dstBegin -- 目標數組中的起始偏移量。
public void setCharAt(int index, char ch),替換index位置的字符;第一個參數是要取代的位置,第二個參數是要取代的字符
public AbstractStringBuilder append(Object obj)//append就是給動態數組添加指定的東西;相當於一個+
public AbstractStringBuilder append(String str)//和上一個的作用一樣
public AbstractStringBuilder append(StringBuffer sb)//給動態數組添加給定StringBuffer的字符序列
AbstractStringBuilder append(AbstractStringBuilder asb)//給動態數組添加給定StringBuilder的字符序列
private AbstractStringBuilder appendNull()//在原字符序列後面添加NUll
public AbstractStringBuilder append(CharSequence s, int start, int end) //在原字符後面添加給定的CharSequence對象,從Strat開始,End結束;
public AbstractStringBuilder append(char[] str)
System.arraycopy(str, 0, value, count, len);;//在原字符後面添加給定的數組
Arraycopyof的用法
函數原型:arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src: 原數組 srcPos:原數組起始的位置
dest:目的數組 destPos:目的數組的起始位置
length:所需複製數組的長度
public AbstractStringBuilder append(char str[], int offset, int len)//在原數組構面添加給定的數組,他是從offset開始,len結束的
public AbstractStringBuilder append(boolean b) //在原數組後面添加字符序列,只能爲true或者false
public AbstractStringBuilder append(char c)//在原數組後面添加指定的字符,是字母
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
append("-2147483648");
return this;
}
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
}//在原數組後面添加指定的字符,先判斷I是否等於Integer中最小數組的長度,如果等於他就添加-2147483648,然後返回值。下面也有同樣的方法,比如append(long l),append(float f),append(double d)
public AbstractStringBuilder delete(int start, int end) //刪除從start開始,end結束的內容,並返回本身
public AbstractStringBuilder appendCodePoint(int codePoint)//向StringBuilder中添加一個Unicode code point 爲 Codepoint的字符,來來,比如appendCodePoint(97) == append(Character.toChars(97))
public AbstractStringBuilder deleteCharAt(int index)//刪除字符爲index的字符,他這個刪除是指定的
public AbstractStringBuilder replace(int start, int end, String str)//替換從start開始,end結束的字符串,這個字符串是Str,在替換的過程中,序列長度會改變
public String substring(int start)//返回一個新的String,它包含的字符目前包含在此字符序列子序列。該子字符串從指定的索引處,並延伸至該序列的結尾。
public CharSequence subSequence(int start, int end)//返回一個新的字符序列,他是此序列的子序列,從Start開始end結束,不包括end,所以只是到end-1;
public String substring(int start, int end)//返回一個新的String,他是從start開始,end結束
public AbstractStringBuilder insert(int index, char[] str, int offset,int len)//個人理解是,他插入了兩個字符,第一個是從index開始插入Str,第二個是從offset開始,插入len
public int indexOf(String str)//返回給定字符在原字符序列第一次出現的位置
public int indexOf(String str, int fromIndex)//返回給定字符在原字符序列中在指定位置之後,第一次出現的位置
public int lastIndexOf(String str)//返回給定字符最後一次出現的位置
public int lastIndexOf(String str, int fromIndex)//返回給定字符串,從右邊開始FromIndex後面第一次出現的位置
public AbstractStringBuilder reverse()//將字符序列反轉
private void reverseAllValidSurrogatePairs()// 在反轉過程中對某些特定的字符做特殊處理,因爲一些字符用UTF-16表示,而char只有8位,存儲這些字符要用兩個char。
emmm.源碼看完了