日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java基础篇:String、StringBuffer、StringBuilder

發(fā)布時(shí)間:2024/9/30 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java基础篇:String、StringBuffer、StringBuilder 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、String:

String并不是基本數(shù)據(jù)類型,而是一個(gè)被final修飾的不可變對(duì)象。通過(guò)查看JDK文檔會(huì)發(fā)現(xiàn)幾乎每一個(gè)修改String對(duì)象的操作,實(shí)際上都是創(chuàng)建了一個(gè)全新的String對(duì)象。

字符串為對(duì)象,那么在初始化之前,它的值為null,到這里就有必要提下null、””、new String()三者的區(qū)別。null 表示string還沒(méi)有new,也就是說(shuō)對(duì)象的引用還沒(méi)有創(chuàng)建,也沒(méi)有分配內(nèi)存空間給他,而””、new String()則說(shuō)明了已經(jīng)new了,只不過(guò)內(nèi)部為空,但是它創(chuàng)建了對(duì)象的引用,是已經(jīng)分配內(nèi)存空間的。打個(gè)比方:一個(gè)空玻璃杯,你不能說(shuō)它里面什么都沒(méi)有,因?yàn)槔锩嬗锌諝?#xff0c;當(dāng)然也可以把它弄成真空,null與" "、new String()的區(qū)別就象真空與空氣一樣。

每當(dāng)我們創(chuàng)建一個(gè)字符串對(duì)象時(shí),首先就會(huì)檢查字符串池中是否存在面值相等的字符串,如果有,則不再創(chuàng)建,直接放回字符串池中對(duì)該對(duì)象的引用,若沒(méi)有則創(chuàng)建然后放入到字符串池中并且返回新建對(duì)象的引用。這個(gè)機(jī)制是非常有用的,因?yàn)榭梢蕴岣咝?#xff0c;減少了內(nèi)存空間的占用。所以在使用字符串的過(guò)程中,推薦使用直接賦值(即String s=”aa”),除非有必要才會(huì)新建一個(gè)String對(duì)象(即String s = new String(”aa”))。

對(duì)于字符串的使用無(wú)非就是這幾個(gè)方面:

1、字符串比較:

==:判斷內(nèi)容與地址是否相同。

equals() :判斷內(nèi)容是否相同。

equalsIgnoreCase():忽略大小寫(xiě)的情況下判斷內(nèi)容是否相同。

compareTo() :判斷字符串的大小關(guān)系。

compareToIgnoreCase(String int) :在比較時(shí)忽略字母大小寫(xiě)。

reagionMatches():對(duì)字符串中的部分內(nèi)容是否相同進(jìn)行比較。

2、字符串查找:

charAt(int index):返回指定索引index位置上的字符,索引范圍從0開(kāi)始。

indexOf(String str):從字符串開(kāi)始檢索str,并返回第一次出現(xiàn)的位置,未出現(xiàn)返回-1。

indexOf(String str,int fromIndex):從字符串的第fromIndex個(gè)字符開(kāi)始檢索str。

lastIndexOf(String str):查找最后一次出現(xiàn)的位置。

lastIndexOf(String str,int fromIndex):從字符串的第fromIndex個(gè)字符查找最后一次出現(xiàn)的位置。

starWith(String prefix,int toffset):測(cè)試此字符串從指定索引開(kāi)始的子字符串是否以指定前綴開(kāi)始。

starWith(String prefix):測(cè)試此字符串是否以指定的前綴開(kāi)始。

endsWith(String suffix):測(cè)試此字符串是否以指定的后綴結(jié)束。

3、字符串截取:

public String subString(int beginIndex):返回一個(gè)新的字符串,它是此字符串的一個(gè)子字符串。

public String subString(int beginIndex,int endIndex):返回的字符串是從beginIndex開(kāi)始到endIndex-1的串。

4、字符串替換:

public String replace(char oldChar,char newChar)。

public String replace(CharSequence target,CharSequence replacement):把原來(lái)的target子序列替換為replacement序列,返回新串。

public String replaceAll(String regex,String replacement):用正則表達(dá)式實(shí)現(xiàn)對(duì)字符串的匹配。注意replaceAll第一個(gè)參數(shù)為正則表達(dá)式。

?

二、StringBuffer:

StringBuffer和String一樣都是用來(lái)存儲(chǔ)字符串的,StringBuffer的許多方法和String類都差不多,所表示的功能幾乎一模一樣。但對(duì)于StringBuffer而言,他在處理字符串時(shí),若是對(duì)其進(jìn)行修改操作,它并不會(huì)像String一樣產(chǎn)生一個(gè)新的字符串對(duì)象,所以說(shuō)在內(nèi)存使用方面它是優(yōu)于String的,這是他們之間最大的區(qū)別。

同時(shí)StringBuffer是不能使用=進(jìn)行初始化的,它必須要產(chǎn)生StringBuffer實(shí)例,也就是說(shuō)你必須通過(guò)它的構(gòu)造方法進(jìn)行初始化。

在StringBuffer的使用方面,它更加側(cè)重于對(duì)字符串的變化,例如追加、修改、刪除,相對(duì)應(yīng)的方法:

append():追加指定內(nèi)容到當(dāng)前StringBuffer對(duì)象的末尾,類似于字符串的連接,這里StringBuffer對(duì)象的內(nèi)容會(huì)發(fā)生改變。

insert:該類方法主要是在StringBuffer對(duì)象中插入內(nèi)容。

delete:該類方法主要用于移除StringBuffer對(duì)象中的內(nèi)容。

?

三、StringBuilder:

? ? ? ? StringBuilder與StringBuffer類似,也是一個(gè)可變的字符串對(duì)象,他與StringBuffer不同之處就在于它是線程不安全的,基于這點(diǎn),它的速度一般都比StringBuffer快。與StringBuffer一樣,StringBuider的主要操作也是append與insert方法。這兩個(gè)方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串,然后將該字符串的字符添加或插入到字符串生成器中。

?

四、正確使用String、StringBuffer、StringBuilder:

前面只是簡(jiǎn)單的介紹了String、StringBuffer、StringBuilder,其實(shí)對(duì)于這三者我們應(yīng)該更加側(cè)重于他們之間的區(qū)別,只有理清楚他們之間的區(qū)別才能夠更好的使用他們。我們先看如下表格:

?類型可變線程安全操作
String字符串變量不可變安全產(chǎn)生一個(gè)新對(duì)象
StringBuffer字符串變量可變安全內(nèi)容發(fā)生改變
StringBuilder字符串變量可變不安全內(nèi)容發(fā)生改變

(1)由于String不可變,所有的操作都是不可能改變其值,因?yàn)閮?nèi)容不可變,永遠(yuǎn)都是安全的。

(2)在使用方面由于String每次修改都需要產(chǎn)生一個(gè)新的對(duì)象,所以對(duì)于經(jīng)常需要改變內(nèi)容的字符串最好選擇StringBuffer或者StringBuilder,而對(duì)于StringBuffer,每次操作都是對(duì)StringBuffer對(duì)象本身,它不會(huì)生成新的對(duì)象,所以StringBuffer特別適用于字符串內(nèi)容經(jīng)常改變的情況下。

(3)并不是所有的String字符串操作都會(huì)比StringBuffer慢,在某些特殊的情況下,String字符串的拼接會(huì)被JVM解析成StringBuilder對(duì)象拼接,在這種情況下String的速度比StringBuffer的速度快。如:

String name = ”I ” + ”am ” + ”chenssy ” ;

StringBuffer name = new StringBuffer(”I ”).append(” am ”).append(” chenssy ”);

對(duì)于這兩種方式,你會(huì)發(fā)現(xiàn)第一種比第二種快太多了,在這里StringBuffer的優(yōu)勢(shì)蕩然無(wú)存。其真實(shí)的原因就在于JVM做了一下優(yōu)化處理,其實(shí)String name = ”I ” + ”am ” + ”chenssy ” ;在JVM眼中就是String name = ”I am chenssy ” ;這樣的方式對(duì)于JVM而言,真的是不要什么時(shí)間。但是如果我們?cè)谶@個(gè)其中增加一個(gè)String對(duì)象,那么JVM就會(huì)按照原來(lái)那種規(guī)范來(lái)構(gòu)建String對(duì)象了。

(4)對(duì)于這三者使用的場(chǎng)景做如下概括:

String:在字符串不經(jīng)常變化的場(chǎng)景中可以使用String類,如:常量的聲明、少量的變量運(yùn)算等。

StringBuffer:在頻繁進(jìn)行字符串的運(yùn)算(拼接、替換、刪除等),并且運(yùn)行在多線程的環(huán)境中,則可以考慮使用StringBuffer,例如XML解析、HTTP參數(shù)解析和封裝等。

StringBuilder:在頻繁進(jìn)行字符串的運(yùn)算(拼接、替換、刪除等),并且運(yùn)行在單線程的環(huán)境中,則可以考慮使用StringBuilder,如SQL語(yǔ)句的拼裝、JSON封裝等。

????? 更多有關(guān)于他們之間區(qū)別,請(qǐng)參考:http://www.cnblogs.com/zuoxiaolong/p/lang1.html。

?

五、字符串拼接方式:

? ? ?對(duì)于字符串而言我們經(jīng)常是要對(duì)其進(jìn)行拼裝處理的,在java中提高了三種拼裝的方法:+、concat()以及append()方法。這三者之間存在什么區(qū)別呢?先看如下示例:

public class StringTest {/*** @desc 使用+、concat()、append()方法循環(huán)10W次* @param args* @return void*/public static void main(String[] args) {//+long start_01 = System.currentTimeMillis();String a = "a";for(int i = 0 ; i < 100000 ; i++){a += "b";}long end_01 = System.currentTimeMillis();System.out.println(" + 所消耗的時(shí)間:" + (end_01 - start_01) + "毫秒");//concat()long start_02 = System.currentTimeMillis();String c = "c";for(int i = 0 ; i < 100000 ; i++){c = c.concat("d");}long end_02 = System.currentTimeMillis();System.out.println("concat所消耗的時(shí)間:" + (end_02 - start_02) + "毫秒");//appendlong start_03 = System.currentTimeMillis();StringBuffer e = new StringBuffer("e");for(int i = 0 ; i < 100000 ; i++){e.append("d");}long end_03 = System.currentTimeMillis();System.out.println("append所消耗的時(shí)間:" + (end_03 - start_03) + "毫秒");} }------------ Output:+ 所消耗的時(shí)間:19080毫秒 concat所消耗的時(shí)間:9089毫秒 append所消耗的時(shí)間:10毫秒

?從上面的運(yùn)行結(jié)果可以看出,append()速度最快,concat()次之,+最慢。原因請(qǐng)看下面分解:

?(一) +方式拼接字符串:

????? 在前面我們知道編譯器對(duì)+進(jìn)行了優(yōu)化,它是使用StringBuilder的append()方法來(lái)進(jìn)行處理的,我們知道StringBuilder的速度比StringBuffer的速度更加快,但是為何運(yùn)行速度還是那樣呢?主要是因?yàn)榫幾g器使用append()方法追加后要同toString()轉(zhuǎn)換成String字符串,也就說(shuō) str +=”b”等同于

????? str = new StringBuilder(str).append("b").toString();

????? 它變慢的關(guān)鍵原因就在于new StringBuilder()和toString(),這里可是創(chuàng)建了10W個(gè)StringBuilder對(duì)象,而且每次還需要將其轉(zhuǎn)換成String,速度能不慢么?

(二)concat()方法拼接字符串:

public String concat(String str) {int otherLen = str.length();if (otherLen == 0) {return this;}char buf[] = new char[count + otherLen];getChars(0, count, buf, 0);str.getChars(0, otherLen, buf, count);return new String(0, count + otherLen, buf);}

?這是concat()的源碼,它看上去就是一個(gè)數(shù)字拷貝形式,我們知道數(shù)組的處理速度是非常快的,但是由于該方法最后是這樣的:return new String(0, count + otherLen, buf);這同樣也創(chuàng)建了10W個(gè)字符串對(duì)象,這是它變慢的根本原因。

(三)append()方法拼接字符串:

public synchronized StringBuffer append(String str) {super.append(str);return this;}

StringBuffer的append()方法是直接使用父類AbstractStringBuilder的append()方法,該方法的源碼如下:

public AbstractStringBuilder append(String str) {if (str == null) str = "null";int len = str.length();if (len == 0) return this;int newCount = count + len;if (newCount > value.length)expandCapacity(newCount);str.getChars(0, len, value, count);count = newCount;return this;}

與concat()方法相似,它也是進(jìn)行字符數(shù)組處理的,加長(zhǎng),然后拷貝,但是請(qǐng)注意它最后是返回并沒(méi)有返回一個(gè)新串,而是返回本身,也就說(shuō)這這個(gè)10W次的循環(huán)過(guò)程中,它并沒(méi)有產(chǎn)生新的字符串對(duì)象。

????? 通過(guò)上面的分析,我們需要在合適的場(chǎng)所選擇合適的字符串拼接方式,但是并不一定就要選擇append()和concat()方法,原因在于+根據(jù)符合我們的編程習(xí)慣,只有到了使用append()和concat()方法確實(shí)是可以對(duì)我們系統(tǒng)的效率起到比較大的幫助,才會(huì)考慮,同時(shí)鄙人也真的沒(méi)有怎么用過(guò)concat()方法。

?

總結(jié)

以上是生活随笔為你收集整理的Java基础篇:String、StringBuffer、StringBuilder的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。