您好,登錄后才能下訂單哦!
這篇文章主要講解了String、StringBuilder、StringBuffer的區別,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
StringBuilder、StringBuffer 和 String 一樣,都是用于存儲字符串的。
1、那既然有了 String ,為什么還需要他們兩個呢?
原因是 String 是不可變的,它每次的字符串拼接,實際上都會 new 一個新的 String 進行接收。
2、談談StringBuilder、StringBuffer他們兩個的聯系:
我們可以知道 StringBuffer 在 1.0 的時候就發布了,那為什么還需要 StringBuilder 呢?原因是它的大部分方法都上了鎖,是線程安全的,導致了效率較低!而我們有時候不需要考慮線程安全問題,追求效率!所以 StringBuilder 在 1.5 的時候就出來了!
3、StringBuilder、StringBuffer 的異同:*
不同:
相同:內部方法和 StringBuffer 完全一致,因為都繼承了 AbstractStringBuilder,底層數組都是用父類的。
4、源碼淺析 String:
結論:final 修飾了底層的字符數組,故內容不可變。
5、源碼淺析 StringBuilder:構造方法
觀察構造方法:
public StringBuilder() { super(16); } public StringBuilder(int capacity) { super(capacity); } public StringBuilder(String str) { super(str.length() + 16); append(str); } public StringBuilder(CharSequence seq) { this(seq.length() + 16); append(seq); }
結論:可以看出,它有一個默認的長度 16!而當傳入參數是一個字符或者字符串時,它也會自動的傳入參數的長度上加上 16!
6、源碼淺析 StringBuilder:append 方法
@Override public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } @Override public StringBuilder append(String str) { super.append(str); return this; }
我們發現,它還是調用的父類的 append 方法,說明這個方法他并沒有重寫,那么 StringBuffer 也一樣!
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; }
結論:我們可以看出,他也是可以拼接 null 的!
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; }
然后觀察,它接著進行了一個數組容量的判斷,而數組的擴容,其實就是在里面實現的,我們點進去看一下!
private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) { value = Arrays.copyOf(value, newCapacity(minimumCapacity)); } }
結論:它先是判斷,當前數組容量+拼接字符 是否大于 數組長度,如果大于,則進行數組拷貝,并將底層數組的引用指向新數組!
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; }
結論:由此可見,新數組長度擴容為原數組的2倍+2 !
問題:那它究竟是怎么拼接字符串的呢?
sb.getChars(0, len, value, count);
進去看一下:String 的 getChars 方法
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { if (srcBegin < 0) throw new StringIndexOutOfBoundsException(srcBegin); if ((srcEnd < 0) || (srcEnd > count)) throw new StringIndexOutOfBoundsException(srcEnd); if (srcBegin > srcEnd) throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); }
實際調用了一個系統類方法:arraycopy,再點進去看一下!
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
結論:底層最終是調用的本地方法,實現了的字符數組拷貝,但由于本地方法是可以和操作系統直接打交道的,所以它的 append 字符串拼接效率會高于 String!
看完上述內容,是不是對String、StringBuilder、StringBuffer的區別有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。