国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

辨析Java中的String與StringBuffer及StringBuilder字符串類(lèi)

2019-11-26 14:19:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

1 String
String:字符串常量,字符串長(zhǎng)度不可變。

2 StringBuffer
StringBuffer:字符串變量(Synchronized,即線(xiàn)程安全)。如果要頻繁對(duì)字符串內(nèi)容進(jìn)行修改,出于效率考慮最好使用StringBuffer,如果想轉(zhuǎn)成String類(lèi)型,可以調(diào)用StringBuffer的toString()方法。
Java.lang.StringBuffer線(xiàn)程安全的可變字符序列。在任意時(shí)間點(diǎn)上它都包含某種特定的字符序列,但通過(guò)某些方法調(diào)用可以改變?cè)撔蛄械拈L(zhǎng)度和內(nèi)容。可將字符串緩沖區(qū)安全地用于多個(gè)線(xiàn)程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類(lèi)型的數(shù)據(jù)。每個(gè)方法都能有效地將?定的數(shù)據(jù)轉(zhuǎn)換成字符串,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點(diǎn)添加字符。例如,如果 z 引用一個(gè)當(dāng)前內(nèi)容是“start”的字符串緩沖區(qū)對(duì)象,則此方法調(diào)用 z.append("le") 會(huì)使字符串緩沖區(qū)包含“startle”,而 z.insert(4, "le") 將更改字符串緩沖區(qū),使之包含“starlet”。

3 StringBuilder
StringBuilder:字符串變量(非線(xiàn)程安全)。
java.lang.StringBuilder是一個(gè)可變的字符序列,是JDK5.0新增的。此類(lèi)提供一個(gè)與 StringBuffer 兼容的 API,但不保證同步。該類(lèi)被設(shè)計(jì)用作 StringBuffer 的一個(gè)簡(jiǎn)易替換,用在字符串緩沖區(qū)被單個(gè)線(xiàn)程使用的時(shí)候(這種情況很普遍)。如果可能,建議優(yōu)先采用該類(lèi),因?在大多數(shù)實(shí)現(xiàn)中,它比 StringBuffer 要快。兩者的方法基本相同。
在大部分情況下,StringBuilder > StringBuffer。

4 三者區(qū)別
String 類(lèi)型和StringBuffer的主要性能區(qū)別:String是不可變的對(duì)象, 因此在每次對(duì) String 類(lèi)型進(jìn)行改變的時(shí)候,都會(huì)生成一個(gè)新的 String 對(duì)象,然后將指針指向新的 String 對(duì)象,所以經(jīng)常改變內(nèi)容的字符串最好不要用 String ,因?每次生成對(duì)象都會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無(wú)引用對(duì)象多了以后, JVM 的 GC 就會(huì)開(kāi)始工作,性能就會(huì)降低。
使用 StringBuffer 類(lèi)時(shí),每次都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象并改變對(duì)象引用。所以多數(shù)情況下推薦使用 StringBuffer ,特別是字符串對(duì)象經(jīng)常改變的情況下。
在某些特別情況下, String 對(duì)象的字符串拼接其實(shí)是被 JVM 解釋成了 StringBuffer 對(duì)象的拼接,所以這些時(shí)候 String 對(duì)象的速度并不會(huì)比 StringBuffer 對(duì)象慢,例如:

 String S1 = “This is only a” + “ simple” + “ test”; StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

生成 String S1 對(duì)象的速度并不比 StringBuffer慢。其實(shí)在 JVM 里,自動(dòng)做了如下轉(zhuǎn)換:

 String S1 = “This is only a” + “ simple” + “test”; 

JVM直接把上述語(yǔ)句當(dāng)作:

String S1 = “This is only a simple test”;

所以速度很快。但要注意的是,如果拼接的字符串來(lái)自另外的String對(duì)象的話(huà),JVM就不會(huì)自動(dòng)轉(zhuǎn)換了,速度也就沒(méi)那么快了,例如:

String S2 = “This is only a”;String S3 = “ simple”;String S4 = “ test”;String S1 = S2 +S3 + S4;

這時(shí)候,JVM 會(huì)規(guī)規(guī)矩矩的按照原來(lái)的方式去做。
在大部分情況下,StringBuffer > String。

4.StringBuffer和StringBuilder
二者幾乎沒(méi)什么區(qū)別,基本都是在調(diào)用父類(lèi)的各個(gè)方法,一個(gè)重要的區(qū)別就是StringBuffer是線(xiàn)程安全的,內(nèi)部的大多數(shù)方法前面都有關(guān)鍵字synchronized,這樣就會(huì)有一定的性能消耗,StringBuilder是非線(xiàn)程安全的,所以效率要高些。

public static void main(String[] args) throws Exception {     String string = "0";     int n = 10000;     long begin = System.currentTimeMillis();     for (int i = 1; i < n; i++) {       string += i;     }     long end = System.currentTimeMillis();     long between = end - begin;     System.out.println("使用String類(lèi)耗時(shí):" + between+"ms");      int n1 = 10000;     StringBuffer sb = new StringBuffer("0");     long begin1 = System.currentTimeMillis();     for (int j = 1; j < n1; j++) {       sb.append(j);     }     long end1 = System.currentTimeMillis();     long between1 = end1 - begin1;     System.out.println("使用StringBuffer類(lèi)耗時(shí):" + between1+"ms");      int n2 = 10000;     StringBuilder sb2 = new StringBuilder("0");     long begin2 = System.currentTimeMillis();     for (int k = 1; k < n2; k++) {       sb2.append(k);     }     long end2 = System.currentTimeMillis();     long between2 = end2 - begin2;     System.out.println("使用StringBuilder類(lèi)耗時(shí):" + between2+"ms");   } 

輸出:

使用String類(lèi)耗時(shí):982ms使用StringBuffer類(lèi)耗時(shí):2ms使用StringBuilder類(lèi)耗時(shí):1ms

雖然這個(gè)數(shù)字每次執(zhí)行都不一樣,而且每個(gè)機(jī)子的情況也不一樣,但是有幾點(diǎn)是確定的,String類(lèi)消耗的明顯比另外兩個(gè)多得多。還有一點(diǎn)就是,StringBuffer要比StringBuilder消耗的多,盡管相差不明顯。


5 使用策略
(1)基本原則:如果要操作少量的數(shù)據(jù),用String ;單線(xiàn)程操作大量數(shù)據(jù),用StringBuilder ;多線(xiàn)程操作大量數(shù)據(jù),用StringBuffer。
(2)不要使用String類(lèi)的"+"來(lái)進(jìn)行頻繁的拼接,因?那?的性能極差的,應(yīng)該使用StringBuffer或StringBuilder類(lèi),這在Java的優(yōu)化上是一條比較重要的原則。舉個(gè)例子:在使用String 的時(shí)候,拼接字符串時(shí)使用“+”在JVM上形成臨時(shí)的StringBuffer對(duì)象,同時(shí)在每一個(gè)字符串上都建立一個(gè)對(duì)象,拼接了兩個(gè)字符串一共需要?jiǎng)?chuàng)建4個(gè)對(duì)象!(一個(gè)保存結(jié)果的String,兩個(gè)字符串對(duì)象,一個(gè)臨時(shí)的StringBuffer對(duì)象)。而使用StringBuffer的話(huà),只需創(chuàng)建2個(gè)對(duì)象!一個(gè)StringBuffer對(duì)象和保存最后結(jié)果的的String對(duì)象 。
(3)?了獲得更好的性能,在構(gòu)造 StirngBuffer 或 StirngBuilder 時(shí)應(yīng)盡可能指定它們的容量。當(dāng)然,如果你操作的字符串長(zhǎng)度不超過(guò) 16 個(gè)字符就不用了。不指定容量會(huì)顯著降低性能。
(4)StringBuilder一般使用在方法內(nèi)部來(lái)完成類(lèi)似"+"功能,因?是線(xiàn)程不安全的,所以用完以后可以丟棄。StringBuffer主要用在全局變量中。
(5)相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線(xiàn)程不安全的風(fēng)險(xiǎn)。而在現(xiàn)實(shí)的模塊化編程中,負(fù)責(zé)某一模塊的程序員不一定能清晰地判斷該模塊是否會(huì)放入多線(xiàn)程的環(huán)境中運(yùn)行,因此:除非確定系統(tǒng)的瓶頸是在 StringBuffer 上,并且確定你的模塊不會(huì)運(yùn)行在多線(xiàn)程模式下,才可以采用StringBuilder;否則還是用StringBuffer。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平远县| 东兴市| 义乌市| 达州市| 南昌县| 绥阳县| 阿合奇县| 崇礼县| 晋中市| 如皋市| 大宁县| 襄垣县| 二连浩特市| 甘德县| 始兴县| 确山县| 晋州市| 耒阳市| 馆陶县| 乌拉特后旗| 泽普县| 肇源县| 荆门市| 武山县| 辰溪县| 平度市| 巫山县| 华池县| 新营市| 蓝田县| 喀什市| 库伦旗| 抚宁县| 佛坪县| 筠连县| 长兴县| 普安县| 安福县| 贵德县| 通河县| 汤阴县|