一層一層的剝開你的心之StringBuilder

今天呢,咋們要來研讀一段代碼,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.源碼看完了

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章