解決StringBuffer和StringBuilder的擴容問題
StringBuffer和StringBuilder的擴容
以前對StringBuffer/StringBuilder隻是初淺的瞭解,隻是知道StringBuffer是線程安全的,Stringbuilder是非線程安全的。並且字符串長度是可變的。
具體是怎麼變沒有去深入瞭解,今天看瞭一下源碼,恍然大悟
來看一下源碼,在沒有傳參的情況下默認初始容量是16。
有參數的情況下,初始容量是16+字符串的長度,並且是用append()方法追加的字符。
到這裡就有疑問那,那這個字符串的長度是多少呢。是它本身的長度還是16+它自身的長度,來接著往下看。一路追尋append()方法終於找到答案瞭。
註意,這個len居然是String自身的長度,現在明白瞭吧。其實平時咱們也在用str.length();方法就是沒註意它的長度是怎麼來的。
忽然又想到一個問題,那要是在追加字符串的時候長度比16大怎麼辦,我們看到有個ensureCapacityInternal()的方法,追進去看看,然後發現它是這麼擴容的
int newCapacity = (value.length << 1) + 2;
增加為自身長度的一倍然後再加2;這個時候如果還是放不下,那就直接擴容到它需要的長度
newCapacity = minCapacity;
StringBuilder擴容規則
StringBuilder默認的創建的時候開辟的char數組的大小
StringBuilder() default 16 StringBuilder("Str") default Str.length()+16
StringBuilder sb擴容的規則:
當調用sb.append()的時候每次都會對當前容量進行判斷
確定下需要的最小的容量(已經存儲的數據長度+準備存儲的數據的長度)是否大於存儲的char數組的長度,如果大於就在newCapacity擴容
判斷擴容當前char數組長度的2倍+2的長度是否滿足擴容需求,不滿足設置為存儲的數據長度+準備存儲的數據的長度,判斷append擴容是否超過MAX_ARRAY_SIZE(Integer.MAX_VALUE – 8),如果是拋出異常OutOfMemoryError
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java中Arraylist的最大長度
- Java中的ArrayList容量及擴容方式
- 關於ArrayList的動態擴容機制解讀
- java中List接口與實現類介紹
- Java有哪些操作字符串的類?區別在哪?