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

首頁 > 學院 > 開發(fā)設計 > 正文

字符串

2019-11-11 02:43:05
字體:
來源:轉載
供稿:網(wǎng)友
可以證明,字符串操作是計算機程序設計中最常見的行為。

      一、String

      首先我們要明確,String并不是基本數(shù)據(jù)類型,而是一個對象,并且是不可變的對象。查看源碼就會發(fā)現(xiàn)String類為final型的(當然也不可被繼承),而且通過查看JDK文檔會發(fā)現(xiàn)幾乎每一個修改String對象的操作,實際上都是創(chuàng)建了一個全新的String對象。

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

      在字符串中存在一個非常特殊的地方,那就是字符串池。每當我們創(chuàng)建一個字符串對象時,首先就會檢查字符串池中是否存在面值相等的字符串,如果有,則不再創(chuàng)建,直接放回字符串池中對該對象的引用,若沒有則創(chuàng)建然后放入到字符串池中并且返回新建對象的引用。這個機制是非常有用的,因為可以提高效率,減少了內(nèi)存空間的占用。所以在使用字符串的過程中,推薦使用直接賦值(即String s=”aa”),除非有必要才會新建一個String對象(即String s = new String(”aa”))。

      對于字符串的使用無非就是這幾個方面:

     1、字符串比較

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

         compareTo() ------判斷字符串的大小關系。

         compareToIgnoreCase(String int) ------在比較時忽略字母大小寫。

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

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

         reagionMatches() ------對字符串中的部分內(nèi)容是否相同進行比較(詳情請參考API)。

     2、字符串查找

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

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

         indexOf(String str,int fromIndex);------從字符串的第fromIndex個字符開始檢索str。

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

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

         starWith(String PRefix,int toffset)-----測試此字符串從指定索引開始的子字符串是否以指定前綴開始。

         starWith(String prefix)------測試此字符串是否以指定的前綴開始。

         endsWith(String suffix)------測試此字符串是否以指定的后綴結束。

     3、字符串截取

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

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

     4、字符串替換

         public String replace(char oldChar,char newChar)。

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

         public String replaceAll(String regex,String replacement)------用正則表達式實現(xiàn)對字符串的匹配。注意replaceAll第一個參數(shù)為正則表達式,鄙人曾經(jīng)深受其害。

     5、更多方法請參考API

      二、StringBuffer

      StringBuffer和String一樣都是用來存儲字符串的,只不過由于他們內(nèi)部的實現(xiàn)方式不同,導致他們所使用的范圍不同,對于StringBuffer而言,他在處理字符串時,若是對其進行修改操作,它并不會產(chǎn)生一個新的字符串對象,所以說在內(nèi)存使用方面它是優(yōu)于String的。

      其實在使用方法,StringBuffer的許多方法和String類都差不多,所表示的功能幾乎一模一樣,只不過在修改時StringBuffer都是修改自身,而String類則是產(chǎn)生一個新的對象,這是他們之間最大的區(qū)別。

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

      在StringBuffer的使用方面,它更加側重于對字符串的變化,例如追加、修改、刪除,相對應的方法:

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

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

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

      三、StringBuilder

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

      上面只是簡單的介紹了String、StringBuffer、StringBuilder,其實對于這三者我們應該更加側重于他們只見到的區(qū)別,只有理清楚他們之間的區(qū)別才能夠更好的使用他們。

     四、正確使用String、StringBuffer、StringBuilder

      我們先看如下表格:

      這里對于String是否為線程安全,鄙人也不是很清楚,原因:String不可變,所有的操作都是不可能改變其值的,是否存在線程安全一說還真不好說?但是如果硬要說線程是否安全的話,因為內(nèi)容不可變,永遠都是安全的。

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

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

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

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

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

      對于這三者使用的場景做如下概括(參考:《編寫搞質量代碼:改善java程序的151個建議》):

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

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

         3、StringBuilder:在頻繁進行字符串的運算(拼接、替換、刪除等),并且運行在多線程的環(huán)境中,則可以考慮使用StringBuffer,如SQL語句的拼裝、JSON封裝等(貌似這兩個我也是使用|StringBuffer)。

      更多有關于他們之間區(qū)別,請參考:http://www.cnblogs.com/zuoxiaolong/p/lang1.html。鄙人就不畫蛇添足了。

      五、字符串拼接方式

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

[java] view plain copy 在CODE上查看代碼片public class StringTest {            /**      * @desc 使用+、concat()、append()方法循環(huán)10W次      * @author chenssy      * @data 2013-11-16      * @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("  +   所消耗的時間:" + (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所消耗的時間:" + (end_02 - start_02) + "毫米");                    //append          long 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所消耗的時間:" + (end_03 - start_03) + "毫米");      }  }    ------------  Output:    +   所消耗的時間:19080毫米  concat所消耗的時間:9089毫米  append所消耗的時間:10毫米  

public%20class%20StringTest%20{%20%20%20%20%20%20%20%20/**%20%20%20%20%20*%20@desc%20使用+、concat()、append()方法循環(huán)10W次%20%20%20%20%20*%20@author%20chenssy%20%20%20%20%20*%20@data%202013-11-16%20%20%20%20%20*%20@param%20args%20%20%20%20%20*%20@return%20void%20%20%20%20%20*/%20%20%20%20public%20static%20void%20main(String[]%20args)%20{%20%20%20%20%20%20%20%20//+%20%20%20%20%20%20%20%20long%20start_01%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20String%20a%20=%20"a";%20%20%20%20%20%20%20%20for(int%20i%20=%200%20;%20i%20<%20100000%20;%20i++){%20%20%20%20%20%20%20%20%20%20%20%20a%20+=%20"b";%20%20%20%20%20%20%20%20}%20%20%20%20%20%20%20%20long%20end_01%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20System.out.println("%20%20+%20%20%20所消耗的時間:"%20+%20(end_01%20-%20start_01)%20+%20"毫米");%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//concat()%20%20%20%20%20%20%20%20long%20start_02%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20String%20c%20=%20"c";%20%20%20%20%20%20%20%20for(int%20i%20=%200%20;%20i%20<%20100000%20;%20i++){%20%20%20%20%20%20%20%20%20%20%20%20c%20=%20c.concat("d");%20%20%20%20%20%20%20%20}%20%20%20%20%20%20%20%20long%20end_02%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20System.out.println("concat所消耗的時間:"%20+%20(end_02%20-%20start_02)%20+%20"毫米");%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//append%20%20%20%20%20%20%20%20long%20start_03%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20StringBuffer%20e%20=%20new%20StringBuffer("e");%20%20%20%20%20%20%20%20for(int%20i%20=%200%20;%20i%20<%20100000%20;%20i++){%20%20%20%20%20%20%20%20%20%20%20%20e.append("d");%20%20%20%20%20%20%20%20}%20%20%20%20%20%20%20%20long%20end_03%20=%20System.currentTimeMillis();%20%20%20%20%20%20%20%20System.out.println("append所消耗的時間:"%20+%20(end_03%20-%20start_03)%20+%20"毫米");%20%20%20%20}}------------Output:%20%20+%20%20%20所消耗的時間:19080毫米concat所消耗的時間:9089毫米append所消耗的時間:10毫米     %20從上面的運行結果可以看出,append()速度最快,concat()次之,+最慢。原因請看下面分解:

     (一)+方式拼接字符串

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

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

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

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

     

[html] view%20plain copy 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);      }  

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

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

public%20synchronized%20StringBuffer%20append(String%20str)%20{%20%20%20%20super.append(str);%20%20%20%20%20%20%20%20return%20this;%20%20%20%20}      StringBuffer的append()方法是直接使用父類AbstractStringBuilder的append()方法,該方法的源碼如下:

[java] view%20plain copy 派生到我的代碼片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()方法相似,它也是進行字符數(shù)組處理的,加長,然后拷貝,但是請注意它最后是返回并沒有返回一個新串,而是返回本身,也就說這這個10W次的循環(huán)過程中,它并沒有產(chǎn)生新的字符串對象。

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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 陆河县| 华坪县| 拜城县| 石城县| 洞口县| 铜陵市| 福州市| 武城县| 阿尔山市| 高邮市| 安平县| 盐边县| 寻甸| 资阳市| 彰化市| 阿克陶县| 石景山区| 祁连县| 张家口市| 攀枝花市| 灌南县| 绥宁县| 瓦房店市| 武安市| 波密县| 桦川县| 福建省| 夏河县| 平塘县| 佛坪县| 吴江市| 大余县| 加查县| 青田县| 自贡市| 通山县| 鹤岗市| 基隆市| 内乡县| 綦江县| 江孜县|