String是Object類的子類誓焦。
StringBuilder和StringBuffer同為AbstractStringBuilder的子類瘩燥,而
AbstractStringBuilder這個抽象類中定義了該參數(shù)
char[] value;
回憶一下在String類的源碼中是這樣定義的;
private final char value[];
兩者的區(qū)別就在于String中的value[]雖然是final但是該引用指向的內(nèi)容是可變的申钩,不過String中沒有提供更改的接口割去,所以內(nèi)容也是不可變的狞玛。反觀AbstractStringBuilder中的value[]則可以供他人更改。
*StringBuilder(可變字符序列)卵洗,String(不可變字符序列)
1.內(nèi)存分析:
舉個例子:我們要把1到100的所有數(shù)字拼起來请唱,組成一個字符串
StringBuffer sbf = new StringBuffer();
for(int i = 0;i<100;i++)
{
sbf.append(i);
}
上面使用StringBuffer和append()方法拼接字符串的方法要比下面使用String的方法高效很多。原因就在于过蹂,String在jvm中是不可變的下面看起來str改變了是因為創(chuàng)建了多個字符串十绑,且讓str指向改變。
這樣一來酷勺,用String來實現(xiàn)的方法會創(chuàng)建101個對象本橙。遠(yuǎn)多于StringBuffer。
String str= new String();
for(int i = 0;i<100;i++)
{
str = str+i;
}
2.動態(tài)數(shù)組擴(kuò)容:數(shù)組一旦創(chuàng)建它的大小就不可變了脆诉。(注:在數(shù)組中l(wèi)ength是屬性甚亭,而在String中l(wèi)ength()是方法,而在StringBuffer的父類AbstractStringBuilder中也有l(wèi)ength方法)那么StringBuffer是如何實現(xiàn)數(shù)組擴(kuò)容的呢击胜?
StringBuffer在擴(kuò)容時會用super()調(diào)用父類的重載構(gòu)造方法亏狰。
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
父類AbstractStringBuilder中:
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
先判斷是否需要擴(kuò)容再講述組擴(kuò)容成原來的2倍加2。并把原來的數(shù)組復(fù)制到新數(shù)組中去偶摔。
3.equals方法的實現(xiàn)重寫:
String中重寫了equals()方法和hashCode()方法暇唾,而StringBuffer并沒有重寫,所以將StringBuffer類儲存進(jìn)集合類中時會出現(xiàn)問題。