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

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

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

    Java語法總結 - 字符串

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

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


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

    2、判斷空字符串。根據需要自己選擇某個或者它們的組合
        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的字符串,和別的字符串的唯一區別就是長度為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文檔時有好處的,要不然花了大量時間實現一個已經存在的方法是很不值得的,因為編寫、測試、維護自己的代碼使項目的成本增加,利潤減少,嚴重的話會導致開不出工資……

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    返回索引頁


    Feedback

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

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

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

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

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

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

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

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

    博主文筆很不錯。

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

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

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

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

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

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

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

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

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

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

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

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

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

    2007-10-22 11:33 by Raylong
    @zhrb
    謝謝??戳四銓懙慕涌诤统橄箢?,以前對此我理解的是不夠全面。呵呵

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

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

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

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

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

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

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

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

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

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

    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()會出現運行時異常呢? 實例變量s1應該會被默認賦值吧。。。不理解。。希望給予回答

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

    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()); //輸出該字符串緩沖區的容量是34”

    應該是33吧
    主站蜘蛛池模板: 日韩视频在线精品视频免费观看| 亚洲最新视频在线观看| 日韩中文字幕精品免费一区| 两个人看的www免费视频中文| 亚洲老熟女五十路老熟女bbw| 亚洲综合久久久久久中文字幕| 亚洲色欲色欲www在线丝| 国产又大又长又粗又硬的免费视频| 亚洲电影免费观看| 国产免费爽爽视频在线观看 | 精品视频一区二区三区免费| 野花视频在线官网免费1| 亚洲中文字幕乱码熟女在线| 亚洲精品无码久久久久久久 | 亚洲电影免费在线观看| 中文字幕不卡高清免费| 四虎国产精品成人免费久久| 美女被暴羞羞免费视频| 色婷婷六月亚洲综合香蕉| 国产精品高清视亚洲一区二区| 亚洲国产模特在线播放| 亚洲精品日韩中文字幕久久久| 久久久久亚洲AV无码永不| 亚洲国产高清在线| 久久精品国产亚洲香蕉| 亚洲人成亚洲人成在线观看 | GOGOGO免费观看国语| 亚洲五月午夜免费在线视频| 全黄A免费一级毛片| 午夜不卡AV免费| 一区二区三区免费视频网站| 亚洲免费无码在线| 中文字幕a∨在线乱码免费看| 国产成人无码精品久久久免费 | 亚洲国产成人久久综合碰| 亚洲AⅤ无码一区二区三区在线| 亚洲国产一成久久精品国产成人综合 | 99re在线这里只有精品免费| 99久热只有精品视频免费看| 精品免费人成视频app | 在线观看日本亚洲一区|