C# 中 StringBuilder和String的区别
大家都知道字符串對(duì)象是“不可變的”,
對(duì)字符串進(jìn)行操作的方法實(shí)際上返回的是新的字符串對(duì)象。
在前面的示例中,將 s1 和 s2 的內(nèi)容連接起來以構(gòu)成一個(gè)字符串時(shí),包含 "orange" 和 "red" 的兩個(gè)字符串均保持不變。+= 運(yùn)算符會(huì)創(chuàng)建一個(gè)包含組合內(nèi)容的新字符串。結(jié)果是 s1 現(xiàn)在引用一個(gè)完全不同的字符串。只包含 "orange" 的字符串仍然存在,但連接 s1 后將不再被引用。
大量的字符串相加的時(shí)候就會(huì)有很多想s1一樣的 不在被引用,從而造成資源的極大浪費(fèi).
我們?cè)诳纯碨tringBuilder是如何處理這樣的問題.
System.Text.StringBuilder?sb?=?new?System.Text.StringBuilder();
sb.Append("one?");
sb.Append("two?");
sb.Append("three");
string?str?=?sb.ToString();
Append方法,Append里面到底是如何實(shí)現(xiàn)的呢.
Append的實(shí)現(xiàn)
public?StringBuilder?Append(string?value)
{
????if?(value?!=?null)
????{
????????string?stringValue?=?this.m_StringValue;
????????IntPtr?currentThread?=?Thread.InternalGetCurrentThread();
????????if?(this.m_currentThread?!=?currentThread)
????????{
????????????stringValue?=?string.GetStringForStringBuilder(stringValue,?stringValue.Capacity);
????????}
????????int?length?=?stringValue.Length;
????????int?requiredLength?=?length?+?value.Length;
????????if?(this.NeedsAllocation(stringValue,?requiredLength))
????????{
????????????string?newString?=?this.GetNewString(stringValue,?requiredLength);
????????????newString.AppendInPlace(value,?length);
????????????this.ReplaceString(currentThread,?newString);
????????}
????????else
????????{
????????????stringValue.AppendInPlace(value,?length);
????????????this.ReplaceString(currentThread,?stringValue);
????????}
????}
????return?this;
}
大家注意這點(diǎn) string stringValue = this.m_StringValue;
internal volatile string m_StringValue;
寫到這里,需要有人見看到了 volatile,也許不明白是什么意思,大概的說下.
volatile關(guān)鍵字實(shí)現(xiàn)了線程間數(shù)據(jù)同步,用volatile修飾后的變量不允許有不同于“主”內(nèi)存區(qū)域的變量拷貝。
換句話說,一個(gè)變量經(jīng)volatile修飾后在所有線程中必須是同步的;任何線程中改變了它的值,所有其他線程立即
獲取到了相同的值。理所當(dāng)然的,volatile修飾的變量存取時(shí)比一般變量消耗的資源要多一點(diǎn),因?yàn)榫€程有它自己的
變量拷貝更為高效。
this.NeedsAllocation(stringValue, requiredLength)
只有在需要的時(shí)候才去重新分配.
就分配空間和線程的使用上來講,StringBuilder肯定比String要高,但是前提是使用頻率比較高的情況下.
====================================================================
使用??? StringBuilder???
?????String??對(duì)象是不可改變的。每次使用??? System.String??? 類中的方法之一時(shí),都要在內(nèi)存中創(chuàng)建一個(gè)新的字符串對(duì)象,這就需要為該新對(duì)象分配新的空間。在需要對(duì)字符串執(zhí)行重復(fù)修改的情況下,與創(chuàng)建新的??? String??? 對(duì)象相關(guān)的系統(tǒng)開銷可能會(huì)非常昂貴。如果要修改字符串而不創(chuàng)建新的對(duì)象,則可以使用?System.Text.StringBuilder?類。
例如,當(dāng)在一個(gè)循環(huán)中將許多字符串連接在一起時(shí),使用??? StringBuilder??? 類可以提升性能。???
????
?? 通過用一個(gè)重載的構(gòu)造函數(shù)方法初始化變量,可以創(chuàng)建??? StringBuilder??? 類的新實(shí)例,如下例
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!");???
????
設(shè)置容量和長(zhǎng)度???
?? 雖然??? StringBuilder??? 對(duì)象是動(dòng)態(tài)對(duì)象,允許擴(kuò)充它所封裝的字符串中字符的數(shù)量,但是您可以為它可容納的最大字符數(shù)指定一個(gè)值。此值稱為該對(duì)象的容量,不應(yīng)將它與當(dāng)前??? StringBuilder??? 對(duì)象容納的字符串長(zhǎng)度混淆在一起。例如,可以創(chuàng)建??? StringBuilder??? 類的帶有字符串“Hello”(長(zhǎng)度為??? 5)的一個(gè)新實(shí)例,同時(shí)可以指定該對(duì)象的最大容量為??? 25。當(dāng)修改??? StringBuilder??? 時(shí),在達(dá)到容量之前,它不會(huì)為其自己重新分配空間。當(dāng)達(dá)到容量時(shí),將自動(dòng)分配新的空間且容量翻倍??梢允褂弥剌d的構(gòu)造函數(shù)之一來指定??? StringBuilder??? 類的容量。以下代碼示例指定可以將??? MyStringBuilder??? 對(duì)象擴(kuò)充到最大??? 25??? 個(gè)空白。???
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!",??? 25);???
????
?? 另外,可以使用讀/寫??? Capacity??? 屬性來設(shè)置對(duì)象的最大長(zhǎng)度。以下代碼示例使用??? Capacity??? 屬性來定義對(duì)象的最大長(zhǎng)度。???
????
?? [C#]???
?? MyStringBuilder.Capacity??? =??? 25;???
????
?? EnsureCapacity??? 方法可用來檢查當(dāng)前??? StringBuilder??? 的容量。如果容量大于傳遞的值,則不進(jìn)行任何更改;但是,如果容量小于傳遞的值,則會(huì)更改當(dāng)前的容量以使其與傳遞的值匹配。???
????
?? 也可以查看或設(shè)置??? Length??? 屬性。如果將??? Length??? 屬性設(shè)置為大于??? Capacity??? 屬性的值,則自動(dòng)將??? Capacity??? 屬性更改為與??? Length??? 屬性相同的值。如果將??? Length??? 屬性設(shè)置為小于當(dāng)前??? StringBuilder??? 對(duì)象內(nèi)的字符串長(zhǎng)度的值,則會(huì)縮短該字符串。???
????
?? 修改??? StringBuilder??? 字符串???
?? 下表列出了可以用來修改??? StringBuilder??? 的內(nèi)容的方法。???
????
?? 方法名??? 使用?????
?? StringBuilder.Append??? 將信息追加到當(dāng)前??? StringBuilder??? 的結(jié)尾。?????
?? StringBuilder.AppendFormat??? 用帶格式文本替換字符串中傳遞的格式說明符。?????
?? StringBuilder.Insert??? 將字符串或?qū)ο蟛迦氲疆?dāng)前??? StringBuilder??? 對(duì)象的指定索引處。?????
?? StringBuilder.Remove??? 從當(dāng)前??? StringBuilder??? 對(duì)象中移除指定數(shù)量的字符。?????
?? StringBuilder.Replace??? 替換指定索引處的指定字符。?????
????
?? Append???
?? Append??? 方法可用來將文本或?qū)ο蟮淖址硎拘问教砑拥接僧?dāng)前??? StringBuilder??? 對(duì)象表示的字符串的結(jié)尾處。以下示例將一個(gè)??? StringBuilder??? 對(duì)象初始化為“Hello??? World”,然后將一些文本追加到該對(duì)象的結(jié)尾處。將根據(jù)需要自動(dòng)分配空間。???
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!");???
?? MyStringBuilder.Append("??? What??? a??? beautiful??? day.");???
?? Console.WriteLine(MyStringBuilder);???
????
?? 此示例將??? Hello??? World!??? What??? a??? beautiful??? day.??? 顯示到控制臺(tái)。???
????
?? AppendFormat???
?? AppendFormat??? 方法將文本添加到??? StringBuilder??? 的結(jié)尾處,而且實(shí)現(xiàn)了??? IFormattable??? 接口,因此可接受格式化部分中描述的標(biāo)準(zhǔn)格式字符串??梢允褂么朔椒▉碜远x變量的格式并將這些值追加到??? StringBuilder??? 的后面。以下示例使用??? AppendFormat??? 方法將一個(gè)設(shè)置為貨幣值格式的整數(shù)值放置到??? StringBuilder??? 的結(jié)尾。???
????
?? [C#]???
?? int??? MyInt??? =??? 25;?????
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Your??? total??? is??? ");???
?? MyStringBuilder.AppendFormat("{0:C}??? ",??? MyInt);???
?? Console.WriteLine(MyStringBuilder);???
????
?? 此示例將??? Your??? total??? is??? $25.00??? 顯示到控制臺(tái)。???
????
?? Insert???
?? Insert??? 方法將字符串或?qū)ο筇砑拥疆?dāng)前??? StringBuilder??? 中的指定位置。以下示例使用此方法將一個(gè)單詞插入到??? StringBuilder??? 的第六個(gè)位置。???
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!");???
?? MyStringBuilder.Insert(6,"Beautiful??? ");???
?? Console.WriteLine(MyStringBuilder);???
????
?? 此示例將??? Hello??? Beautiful??? World!??? 顯示到控制臺(tái)。???
????
?? Remove???
?? 可以使用??? Remove??? 方法從當(dāng)前??? StringBuilder??? 中移除指定數(shù)量的字符,移除過程從指定的從零開始的索引處開始。以下示例使用??? Remove??? 方法縮短??? StringBuilder。???
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!");???
?? MyStringBuilder.Remove(5,7);???
?? Console.WriteLine(MyStringBuilder);???
????
?? 此示例將??? Hello??? 顯示到控制臺(tái)。???
????
Replace???
?? 使用??? Replace??? 方法,可以用另一個(gè)指定的字符來替換??? StringBuilder??? 對(duì)象內(nèi)的字符。以下示例使用??? Replace??? 方法來搜索??? StringBuilder??? 對(duì)象,查找所有的感嘆號(hào)字符??? (!),并用問號(hào)字符??? (?)??? 來替換它們。???
????
?? [C#]???
?? StringBuilder??? MyStringBuilder??? =??? new??? StringBuilder("Hello??? World!");???
?? MyStringBuilder.Replace('!',??? '?');???
?? Console.WriteLine(MyStringBuilder);???
????
?? 此示例將??? Hello??? World???? 顯示到控制臺(tái)。
轉(zhuǎn)載于:https://www.cnblogs.com/zhang-chao/archive/2009/11/02/1594563.html
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的C# 中 StringBuilder和String的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python property函数_Py
- 下一篇: 【转】英语生活箴言