【優(yōu)雅編程之道】之字符串的5點建議

開心一笑

【一個本科男找了一個女博士。新春佳節(jié),本科男紿女博士發(fā)了一個520元的紅包,附言:我愛你。稍后,女博士給本科男發(fā)了一個5.20元的紅包,并附言:我愛你多一點!本科男感嘆道:有文化,太可怕,少花錢,會說話!】

提出問題

項目中如何優(yōu)雅使用字符串 ???

唯美圖片

解決問題

初始化字符串的兩種選擇比較

例:

//第一種初始化字符串方式
String str = "ay";
String str2 = "ay";
System.out.println(str == str2);
//第二種初始化字符串方式
String newStr = new String("ay");
System.out.println(str == newStr);

//打印結(jié)果
true
false

通過上面實例,我們可以看到:第一種初始化字符串的方法,事實上是把字符串放到常量池里面。當(dāng)創(chuàng)建 str2 字符串的時候,它會到常量池尋找,找不到,就創(chuàng)建之。找到了,就把對象引用傳給 str2 。因為 String 類是 final 的且 String 的所有方法有返回的 String 字符串的,都會重新新建一個新的 String 對象。所有不會有線程安全問題。綜上所述,建議大家在以后開發(fā)過程中,使用第一種方式,優(yōu)雅的創(chuàng)建字符串。

字符串常量equals時候?qū)⒆址A繉懺谇懊?/h4>

判斷字符相等是最常見的情景,例如:

@Test
public void test(){

    String str = "ay";
    if(str.equals("ay")){
        System.out.println("不推薦寫法");
    }
    String str2 = null;
    if("ay".equals(str2)){
        System.out.println("推薦寫法");
    }
    if(str2.equals("ay")){
        System.out.println("出現(xiàn) NullPointerException 異常");
    }
}

如果我們把字符常量 ay 寫在 equals 前面,即使兩個字符串不相等,也不會產(chǎn)生空指針異常。可以達(dá)到優(yōu)雅的判斷是否相等。

for循環(huán)中不寫字符串拼接

我們知道,for循環(huán)中,除了不要做數(shù)據(jù)庫連接,查詢數(shù)據(jù)庫和處理異常外。在循環(huán)次數(shù)比較多的for循環(huán)中,我們也不要利用 + 號去拼接字符串。具體例子如下:

程序清單 1-1

@Test
public void test(){
    String str = "ay";
    for(int i=0;i<Integer.MAX_VALUE;i++){
         str = str + i;
    }
}

這個問題也是老生常談的了。具體解決方法如下:

  • 根據(jù)具體的業(yè)務(wù)場景,使用 StringBuffer(線程安全)或者 StringBuilder(非線程安全)
  • 使用數(shù)組
程序清單 1-1

@Test
public void test(){
    //第一種解決方法
    StringBuilder stringBuilder = new StringBuilder(Integer.MAX_VALUE);
    //第二種解決方法
    String[] strArray = new String[Integer.MAX_VALUE + 1];
    stringBuilder.append("ay");
    strArray[0] = "ay";
    for(int i=0;i<Integer.MAX_VALUE + 1;i++){
        stringBuilder.append("al");
        strArray[i + 1] = "al";
    }
    System.out.println(stringBuilder.toString());
    System.out.println(ArrayUtils.toString(strArray));
}

不過,java在長久的發(fā)展歷程中,編譯器會對字符串拼接進(jìn)行優(yōu)化。但是在多種可選的方案下,我建議大家使用最優(yōu)雅的方式去實現(xiàn)字符串拼接,就是 StringBuffer(線程安全)或者 StringBuilder(非線程安全)

設(shè)置容量參數(shù)提高系統(tǒng)性能

對于 StringBuffer(線程安全)或者 StringBuilder(非線程安全),都有相應(yīng)的構(gòu)造方法:

程序清單 1-1

public StringBuilder(int capacity) {
    super(capacity);
}

如果我們可以事先知道需要拼接的字符串長度,設(shè)置容量參數(shù),防止 StringBuffer 在源碼內(nèi)部進(jìn)行一系列復(fù)雜的內(nèi)存復(fù)制操作,影響性能。

如上面的

StringBuilder stringBuilder = new StringBuilder(Integer.MAX_VALUE);

實現(xiàn)高性能的字符串分割

實現(xiàn)字符串的分割的方法有很多種,常用的是 split ,StringTokenizer ,indexOf 和 substring 的配合,以及一些開源工具類,如:StringUtils。它們各有優(yōu)缺。

@Test
public void test(){
    //數(shù)據(jù)初始化
    StringBuffer sb = new StringBuffer();
    for(int i=0;i<10000;i++){
        sb.append(i).append(";");
    }
    String originStr = sb.toString();
    //第一種分隔字符方法
    long startTime = System.nanoTime();

    String[] splitArray =  originStr.split(";");
    for(int i=0,len = splitArray.length;i<len;i++){
        String temp = splitArray[i];
    }
    long endTime = System.nanoTime();
    System.out.println("the cost of split is :" + (endTime - startTime));
    //第二種分隔字符方法
    System.out.println("--------------------------------------------");
    originStr = sb.toString();
    startTime = System.nanoTime();
    StringTokenizer st = new StringTokenizer(originStr,";");
    while(st.hasMoreTokens()){
        st.nextToken();
    }
    endTime = System.nanoTime();
    System.out.println("the cost of stringTokenizer is :" + (endTime - startTime));
    //第三種分隔字符的方法
    System.out.println("--------------------------------------------");
    originStr = sb.toString();
    startTime = System.nanoTime();
    while (true){
        int index = originStr.indexOf(";");
        if(index < 0) break;
        String origin = originStr.substring(0,index);
        originStr = originStr.substring(index + 1);
    }
    endTime = System.nanoTime();
    System.out.println("the cost of indexOf is :" + (endTime - startTime));

    //第四種分隔字符的方法
    System.out.println("--------------------------------------------");
    originStr = sb.toString();
    startTime = System.nanoTime();
    String[] utilSplit = StringUtils.split(originStr,';');
    for(int i=0,len = utilSplit.length;i<len;i++){
        String temp = utilSplit[i];
    }
    endTime = System.nanoTime();
    System.out.println("the cost of StringUtils.split is :" + (endTime - startTime));

}

運行結(jié)果:

the cost of split is :35710479
--------------------------------------------
the cost of stringTokenizer is :11992643
--------------------------------------------
the cost of indexOf is :323050471
--------------------------------------------
the cost of StringUtils.split is :59026333

從上面例子可以看出,字符分割的性能,由高到低的排序為:StringTokenizer > split ,StringUtils.split > indexOf 。有些書籍寫著 indexOf 的性能是最高的,但是按照我的測試,index的性能是最差的。但是事物都有兩面性,從上面的例子也可以看出,雖然 StringTokenizer 的性能高,但是代碼量多,可讀性差,而 split 代碼相對就整潔多了。

讀書感悟

來自《我腦袋里的怪東西》

  • 讓一千萬人聚集在伊斯坦布爾的東西是生計、利益、帳單,但支撐這茫茫人海的只有一樣?xùn)|西,那就是愛!
  • 身處城市熙熙攘攘的人群中,也可能感到孤獨,但是讓城市成為城市的東西,也恰恰是這種能夠在人群中隱藏自己頭腦里的怪念頭的可能。
  • 有時覺得,自己正在經(jīng)歷人生中最幸福的歲月,但只把這種感覺存放在腦海的一個角落里。因為擔(dān)心,如果總想著自己幸福,就可能失去它。

經(jīng)典故事

【一只烏鴉坐在樹上,整天無所事事。一只小兔子看見烏鴉,就問:“我能象你一樣整天坐在那里,什么事也不干嗎?”烏鴉答道:“當(dāng)然啦,為什么不呢?”于是,兔子便坐在樹下,開始休息。突然,一只狐貍出現(xiàn)了。狐貍跳向兔子……并把它給吃了。這個故事的寓意是……要想坐在那里什么也不干,你必須坐(做)得非常非常高】

大神文章

【1】《Agile Java》
【2】《Java程序性能優(yōu)化 讓你的Java程序更快、更穩(wěn)定》
【3】《Thinking in Java (Java編程思想)》
【4】《編寫高質(zhì)量代碼:改善Java程序的151個建議》

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎點贊、頂、歡迎留下寶貴的意見、多謝支持!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,806評論 3 93
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,727評論 18 399
  • 集合框架: 1)特點:存儲對象;長度可變;存儲對象的類型可不同2)Collection(1)List:有序的;元素...
    Demo_Yang閱讀 1,386評論 0 4
  • 遠(yuǎn)方的世界能否足夠誘惑 可知一心遠(yuǎn)方獨往的我 曾幾何時一起走過的歲月 已沒有了溫暖留戀的你 只是...
    念江子閱讀 160評論 0 2
  • 相見恨晚啊,認(rèn)識簡書主要來源于百度搜索Android studio后看到Tikitoo的一篇文章《Android...
    leeqico閱讀 262評論 0 1

友情鏈接更多精彩內(nèi)容