<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java語法總結(jié) - 字符串

    Posted on 2007-10-21 12:47 Raylong 閱讀(5660) 評論(17)  編輯  收藏 所屬分類: Java語法總結(jié)
    Java語法總結(jié) - 字符串

    Java的String太特別了,也太常用了,所以重要。我初學Java就被它搞蒙了,太多混淆的概念了,比如它的不變性。所以必須深入機制地去理解它。


    1、String中的每個字符都是一個16位的Unicode字符,用Unicode很容易表達豐富的國際化字符集,比如很好的中文支持。甚至Java的標識符都可以用漢字,但是沒人會用吧(只在一本清華的《Java2實用教程》看過)。

    2、判斷空字符串。根據(jù)需要自己選擇某個或者它們的組合
        if ( s == null )    //從引用的角度
        if ( s.length() == 0 )     //從長度判別
        if ( s.trim().length () == 0 )     //是否有多個空白字符
    trim()方法的作用是是移除前導和尾部的Unicode值小于'"u0020'的字符,并返回“修剪”好的字符串。這種方法很常用,比如需要用戶輸入用戶名,用戶不小心加了前導或者尾部空格,一個好的程序應該知道用戶不是故意的,即使是故意的也應該智能點地處理。
    判斷空串是很常用的操作,但是Java類庫直到1.6才提供了isEmpty()方法。當且僅當 length() 為 0 時返回 true。

    3、未初始化、空串""與null。它們是不同的概念。對未初始化的對象操作會被編譯器擋在門外;null是一個特殊的初始化值,是一個不指向任何對象的引用,對引用為null的對象操作會在運行時拋出異常NullPointerException;而空串是長度為0的字符串,和別的字符串的唯一區(qū)別就是長度為0。
    例子:
        public class StringTest{
            static String s1;
            public static void main(String[] args) {
                String s2;
                String s3 = "";
                System.out.print(s1.isEmpty());     //運行時異常
                System.out.print(s2.isEmpty());     //編譯出錯
                System.out.print(s3.isEmpty());     //ok!輸出true
            }
        }

    4、String類的方法很多,在編寫相關代碼的時候看看JDK文檔時有好處的,要不然花了大量時間實現(xiàn)一個已經(jīng)存在的方法是很不值得的,因為編寫、測試、維護自己的代碼使項目的成本增加,利潤減少,嚴重的話會導致開不出工資……

    5、字符串的比較。
    Java不允許自定義操作符重載,因此字符串的比較要用compareTo() 或者 compareToIgnoreCase()。s1.compareTo(s2),返回值大于0則,則前者大;等于0,一般大;小于0,后者大。比較的依據(jù)是字符串中各個字符的Unicode值。

    6、toString()方法。
    Java的任何對象都有toString()方法,是從Object對象繼承而來的。它的作用就是讓對象在輸出時看起來更有意義,而不是奇怪的對象的內(nèi)存地址。對測試也是很有幫助的。

    7、String對象是不變的!可以變化的是String對象的引用。
    String name = "ray";
    name.concat("long");  //字符串連接
    System.out.println(name); //輸出name,ok,還是"ray"
    name = name.concat("long");  //把字符串對象連接的結(jié)果賦給了name引用
    System.out.println(name);  //輸出name,oh!,變成了"raylong"
    上述三條語句其實產(chǎn)生了3個String對象,"ray","long","raylong"。第2條語句確實產(chǎn)生了"raylong"字符串,但是沒有指定把該字符串的引用賦給誰,因此沒有改變name引用。第3條語句根據(jù)不變性,并沒有改變"ray",JVM創(chuàng)建了一個新的對象,把"ray","long"的連接賦給了name引用,因此引用變了,但是原對象沒變。

    8、String的不變性的機制顯然會在String常量內(nèi)有大量的冗余。如:"1" + "2" + "3" +......+ "n" 產(chǎn)生了n+(n+1)個String對象!因此Java為了更有效地使用內(nèi)存,JVM留出一塊特殊的內(nèi)存區(qū)域,被稱為“String常量池”。對String多么照顧啊!當編譯器遇見String常量的時候,它檢查該池內(nèi)是否已經(jīng)存在相同的String常量。如果找到,就把新常量的引用指向現(xiàn)有的String,不創(chuàng)建任何新的String常量對象。

    那么就可能出現(xiàn)多個引用指向同一個String常量,會不會有別名的危險呢?No problem!String對象的不變性可以保證不會出現(xiàn)別名問題!這是String對象與普通對象的一點區(qū)別。

    乍看起來這是底層的機制,對我們編程沒什么影響。而且這種機制會大幅度提高String的效率,實際上卻不是這樣。為連接n個字符串使用字符串連接操作時,要消耗的時間是n的平方級!因為每兩個字符串連接,它們的內(nèi)容都要被復制。因此在處理大量的字符串連接時,而且要求性能時,我們不要用String,StringBuffer是更好的選擇。

    8、StringBuffer類。StringBuffer類是可變的,不會在字符串常量池中,而是在堆中,不會留下一大堆無用的對象。而且它可將字符串緩沖區(qū)安全地用于多個線程。每個StringBuffer對象都有一定的容量。只要StringBuffer對象所包含的字符序列的長度沒有超出此容量,就無需分配新的內(nèi)部緩沖區(qū)數(shù)組。如果內(nèi)部緩沖區(qū)溢出,則此容量自動增大。這個固定的容量是16個字符。我給這種算法起個名字叫“添飯算法”。先給你一滿碗飯,不夠了再給你一滿碗飯。
    例子:
        StringBuffer sb = new StringBuffer();    //初始容量為 16 個字符
        sb.append("1234");    //這是4個字符,那么16個字符的容量就足夠了,沒有溢出
        System.out.println(sb.length());    //輸出字符串長度是4
        System.out.println(sb.capacity());    //輸出該字符串緩沖區(qū)的容量是16

        sb.append("12345678901234567");        //這是17個字符,16個字符的容量不夠了,擴容為17+16個字符的容量
        System.out.println(sb.length());    //輸出字符串長度是17
        System.out.println(sb.capacity());    //輸出該字符串緩沖區(qū)的容量是34

        sb.append("890").reverse().insert(10,"-");    
        System.out.println(sb);        //輸出0987654321-09876543214321

    字符串的長度和字符緩沖區(qū)的容量是兩個概念,注意區(qū)別。
    還有串聯(lián)的方式看起來是不是很酷!用返回值連接起來可以實現(xiàn)這種簡潔和優(yōu)雅。

    10、StringBuilder類。 從J2SE 5.0 提供了StringBuilder類,它和StringBuffer類是孿生兄弟,很像。它存在的價值在于:對字符串操作的效率更高。不足的是線程安全無法保證,不保證同步。那么兩者性能到底差多少呢?很多!
    請參閱:http://book.csdn.net/bookfiles/135/1001354628.shtml
    實踐:
    單個線程的時候使用StringBuilder類,以提高效率,而且它的API和StringBuffer兼容,不需要額外的學習成本,物美價廉。多線程時使用StringBuffer,以保證安全。

    11、字符串的比較。
    下面這條可能會讓你暈,所以你可以選擇看或者不看。它不會對你的職業(yè)生涯造成任何影響。而且謹記一條,比較字符串要用equals()就ok了!一旦用了“==”就會出現(xiàn)很怪異的現(xiàn)象。之所以把這部分放在最后,是想節(jié)省大家的時間,因為這條又臭又長。推薦三種人:一、沒事閑著型。二、想深入地理解Java的字符串,即使明明知道學了也沒用。三、和我一樣愛好研究“茴”字有幾種寫法。

    還是那句老話,String太特殊了,以至于某些規(guī)則對String不起作用。個人感覺這種特殊性并不好。看例子:
    例子A:
        String str1 = "java";
        String str2 = "java";
        System.out.print(str1==str2);
    地球上有點Java基礎的人都知道會輸出false,因為==比較的是引用,equals比較的是內(nèi)容。不是我忽悠大家,你們可以在自己的機子上運行一下,結(jié)果是true!原因很簡單,String對象被放進常量池里了,再次出現(xiàn)“java”字符串的時候,JVM很興奮地把str2的引用也指向了“java”對象,它認為自己節(jié)省了內(nèi)存開銷。不難理解吧 呵呵
    例子B:
        String str1 = new String("java");
        String str2 = new String("java");
        System.out.print(str1==str2);
    看過上例的都學聰明了,這次肯定會輸出true!很不幸,JVM并沒有這么做,結(jié)果是false。原因很簡單,例子A中那種聲明的方式確實是在String常量池創(chuàng)建“java”對象,但是一旦看到new關鍵字,JVM會在堆中為String分配空間。兩者聲明方式貌合神離,這也是我把“如何創(chuàng)建字符串對象”放到后面來講的原因。大家要沉住氣,還有一個例子。
    例子C:
        String str1 = "java";
        String str2 = "blog";
        String s = str1+str2;
        System.out.print(s=="javablog");
    再看這個例子,很多同志不敢妄言是true還是false了吧。愛玩腦筋急轉(zhuǎn)彎的人會說是false吧……恭喜你,你會搶答了!把那個“吧”字去掉你就完全正確。原因很簡單,JVM確實會對型如String str1 = "java"; 的String對象放在字符串常量池里,但是它是在編譯時刻那么做的,而String s = str1+str2; 是在運行時刻才能知道(我們當然一眼就看穿了,可是Java必須在運行時才知道的,人腦和電腦的結(jié)構(gòu)不同),也就是說str1+str2是在堆里創(chuàng)建的,s引用當然不可能指向字符串常量池里的對象。沒崩潰的人繼續(xù)看例子D。
    例子D:
        String s1 = "java";
        String s2 = new String("java");
        System.out.print(s1.intern()==s2.intern());
    intern()是什么東東?反正結(jié)果是true。如果沒用過這個方法,而且訓練有素的程序員會去看JDK文檔了。簡單點說就是用intern()方法就可以用“==”比較字符串的內(nèi)容了。在我看到intern()方法到底有什么用之前,我認為它太多余了。其實我寫的這一條也很多余,intern()方法還存在諸多的問題,如效率、實現(xiàn)上的不統(tǒng)一……
    例子E:
        String str1 = "java";
        String str2 = new String("java");
        System.out.print(str1.equals(str2));
    無論在常量池還是堆中的對象,用equals()方法比較的就是內(nèi)容,就這么簡單!看完此條的人一定很后悔,但是在開始我勸你別看了……

    后記:用彪哥的話說“有意思嗎?”,確實沒勁。在寫這段的時候我也是思量再三,感覺自己像孔乙己炫耀“茴”字有幾種寫法。我查了一下茴 ,回,囘,囬,還有一種是“口”字里面有個“目”字,后面這四個都加上草字頭……

    返回索引頁


    Feedback

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 13:46 by 翔南
    恩 又對String有了更深的理解
    第一次聽說還有個常量池的東西,學習了.
    還有那個isEmpty()方法很nice!

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 13:51 by Raylong
    @翔南
    isEmpty()早該有了,對不?

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 13:59 by 翔南
    呵呵 的確
    要不每次都得自己判斷..

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 14:13 by 海邊沫沫
    寫得蠻好。看了收獲不小。

    博主文筆很不錯。

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 15:40 by Raylong
    @海邊沫沫
    謝謝夸獎,這個還沒總結(jié)完呢,還要加更多的內(nèi)容。

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 17:07 by 推薦java開源項目介紹大全《敏捷之源 - agilesource.org》
    文筆不錯~

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 19:20 by Raylong
    @推薦java開源項目介紹大全《敏捷之源 - agilesource.org》
    謝謝!我會繼續(xù)努力補完的,到時候語法基礎就夯實了

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 21:27 by 極品飛車
    文章很不錯,就是黑底白字的顏色搭配閱讀相當不舒服,最標準的顏色搭配是白底黑字

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-21 23:04 by Raylong
    @極品飛車
    多數(shù)網(wǎng)站都是白底黑字吧,但是黑色能給我寧靜的感覺。我也在想一種搭配,把白字換成更柔和的顏色,不知道你有什么建議?

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-22 09:13 by zhrb
    還不錯,幫忙頂頂。呵呵

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-22 11:33 by Raylong
    @zhrb
    謝謝。看了你寫的接口和抽象類,以前對此我理解的是不夠全面。呵呵

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-22 12:15 by zhrb
    @Raylong
    我寫得那些只是部分的思考,后來陸續(xù)看了一些文章才發(fā)現(xiàn)那些理解還遠遠不夠
    可能更深入的思考要在讀過、寫過大量的源代碼之后才有可能實現(xiàn)
    你的blog很好,我會一直關注的。呵呵

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-10-22 12:29 by Raylong
    @zhrb
    是啊,我現(xiàn)在想明白了,上來就看TIJ是行不通的,根本理解不到那個層次。必須從基礎開始多做練習,寫代碼,看代碼。

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-11-04 21:10 by 糖果屋-Tocas

    看了博主幾篇文章,感覺很好,很嚴謹,講問題也講的很透徹!fighting

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2007-12-26 14:59 by pm6422
    null是一個特殊的初始化值,是一個不指向任何對象的引用,因此不能夠使用該類的所有方法,如果使用則會在運行時拋出NullPointerException,但是可以對null的對象進行一部分操作;如:String str=null; str=str+"aa";

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2009-01-28 22:58 by li002qwe
    public class StringTest{
    static String s1;
    public static void main(String[] args) {
    String s2;
    String s3 = "";
    System.out.print(s1.isEmpty()); //運行時異常
    System.out.print(s2.isEmpty()); //編譯出錯
    System.out.print(s3.isEmpty()); //ok!輸出true
    }
    }

    為什么s1.isEmpty()會出現(xiàn)運行時異常呢? 實例變量s1應該會被默認賦值吧。。。不理解。。希望給予回答

    # re: Java語法總結(jié) - 字符串  回復  更多評論   

    2012-05-09 11:40 by xc
    “sb.append("12345678901234567"); //這是17個字符,16個字符的容量不夠了,擴容為17+16個字符的容量
    System.out.println(sb.length()); //輸出字符串長度是17
    System.out.println(sb.capacity()); //輸出該字符串緩沖區(qū)的容量是34”

    應該是33吧
    主站蜘蛛池模板: 欧美日韩亚洲精品| 亚洲女人初试黑人巨高清| 亚洲国产成人久久一区二区三区| 88av免费观看入口在线| 亚洲精品高清久久| 18女人毛片水真多免费| 亚洲欧洲日产国产综合网| 国产精品区免费视频| 亚洲午夜精品久久久久久人妖 | 亚洲一区二区三区播放在线| 精品一区二区三区无码免费视频| 亚洲Aⅴ无码专区在线观看q| 99精品一区二区免费视频| 亚洲图片一区二区| 无码国产精品一区二区免费式直播| 亚洲人和日本人jizz| 卡一卡二卡三在线入口免费| 黄色网址免费在线| 亚洲午夜福利717| 久久精品无码专区免费青青| 亚洲一级毛片在线播放| 在线免费观看一区二区三区| 日韩大片免费观看视频播放| 亚洲性猛交XXXX| 日本免费久久久久久久网站| 99999久久久久久亚洲| 国产一卡二卡≡卡四卡免费乱码| 伊人久久国产免费观看视频| 亚洲成年人在线观看| 欧美在线看片A免费观看| 国产91成人精品亚洲精品| 国产AV无码专区亚洲Av| 999国内精品永久免费观看| 黄色一级毛片免费| 777亚洲精品乱码久久久久久 | www成人免费观看网站| 亚洲成AV人片一区二区密柚| 成人无码区免费A片视频WWW| 免费看一级高潮毛片| 亚洲av伊人久久综合密臀性色| 日本免费xxxx|