JAVA中的字符串小結


String字符串是只讀的,不可變的

查看String類的源碼,可以發現String類是被final關鍵字修飾的;

另外還可以看下String類源碼中的其它方法實現,隨便舉個可以修改String值的方法,如字符串拼接方法concat(String str),返回的是一個全新的String對象,而不是在原有的String對象上做修改,代碼如下:

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

以上代碼中,將原有的字符數組和新字符串數組拷貝到一個新的字符數組中,然后new出一個新的String對象返回;

重載“+”與StringBuilder

 先看一段使用“+”拼接字符串的代碼如下:

package strings;

public class Test {

    public static void main(String[] args) {
        String a = "test";                
        String b = a;                //b保存了a的引用
        
        //這里編譯器會為我們自動創建StringBuilder對象,並調用append方法,
        //最終調用StringBuilder的toString方法返回一個新的字符串對象
        a = a + "1" + "2" + "3";    //生成了一個新的String對象賦給a
        
        System.out.println(b==a);    //引用a指向了新的字符串對象,不相等
        System.out.println(a);
    }
}

在使用“+”拼接字符串的時候,編譯器會為我們自動創建StringBuilder對象,並調用append方法拼接字符串,最終調用StringBuilder的toString方法返回一個新的字符串對象;

或許你認為既然編譯器會為我們創建自動StringBuilder對象就可以任意使用“+”操作符了,實際上編譯器在某些情況下為我們優化的程度還是不夠,如下代碼例子,在循環體內使用“+”操作符;

package strings;

public class Test {

    public static void main(String[] args) {
        String a = "";                
        for(int i = 0;  i < 5; i++){
            //編譯器每次都會生成一個StringBuilder對象,並調用toString方法生成一個新的String對象
            //這中間產生了兩個臨時對象
            a +=i;
        }
        System.out.println(a);
    }
}

可以使用eclipse調試進入源碼,會發現,編譯器每次都會生成一個StringBuilder對象,並調用toString方法生成一個新的String對象,也就是說。每循環體執行一次,就產生了兩個臨時對象,可見,當循環次數大的時候,會產生一大堆需要垃圾回收的中間對象,而直接使用StringBuilder就沒有這種情況,如下代碼,為一個正確的例子:

package strings;

public class Test {

    public static void main(String[] args) {
        StringBuilder a = new StringBuilder("");                
        for(int i = 0;  i < 5; i++){
            a.append(i);
        }
        System.out.println(a);
    }
}

總之,只要涉及字符串的操作,選擇StringBuilder總是沒錯的;

無意識的遞歸調用

在重寫toString方法的時候,如果不注意使用了this關鍵字,很有可能會調入遞歸調用的陷阱,如下代碼:

package strings;

public class Test {

    @Override
    public String toString() {
        
        return "addr:" + this;
    }
    
    public static void main(String[] args) {            
        Test t = new Test();
        System.out.println(t);
    }
}

執行的時候,將拋出StackOverflowError異常,因為toString方法里的"addr:" + this語句會調用自身toString方法,導致無窮無盡的遞歸調用,然后堆棧溢出,拋出異常;

如果你僅僅是想打印下對象的地址,那么可以調用super.toString()方法,因為Object對象的toString方法默認會調用hashCode打印對象地址;

Sting類的方法

關於String類中的方法,可以查看String源碼或JDK的API文檔,相對來說還是很好理解的,所謂String對象,實質上來說就是一個字符數組;

String類中的方法,大部分都是操作String內部維護的char value[]數組實現的;

主要方法如下,圖片參考自java編程思想-4:

字符串格式化輸出

關於格式化輸出,了解以下幾個例子吧:

format方法:可用於PrintString和PritWriter, 如System.out.format, 如果有C語言的printf語法的使用經驗的話,學習format語法會非常輕松,基本類似,如下為一個簡單例子:

System.out.format("%5d: %2f", 101,1.131452);

Formatter類:printf 風格的格式字符串的解釋程序,如下例子:

package strings;

import java.util.Formatter;

public class Test {

    public static void main(String[] args) {
        Formatter formatter = new Formatter(System.out);
        formatter.format("%5d: %2f", 101, 1.131452);
        formatter.close();
    }
}

String.format方法:String類的靜態方法,在其內部實際上也是通過創建Formatter對象實現的;

System.out.println(String.format("%5d: %2f", 101, 1.131452));

正則表達式

關於正則表達式的具體語法就不細說了,在String類中,涉及正則表達式的主要是以下方法:

matches:判斷是否匹配指定的正則表達式規則

split:分割字符串

replaceAll/replaceFirst:將匹配的字符替換為指定的字符串

如下代碼為一個簡單的使用例子:

package strings;

public class RegexTest {
    public static void main(String[] args) {
        
        //匹配數字
        System.out.println("1314".matches("\\d+"));

        //按數字分割
        String[] splitArr = "asdashh45hiu9jkjaks54d".split("-?\\d+");
        for(String str:splitArr){
            System.out.print(str + ", ");
        }
        
        //替換數字為*號
        System.out.println();
        System.out.println("asdashh45hiu9jkjaks54d".replaceAll("-?\\d+", "*"));
        
    }
}
//輸出
//true
//asdashh, hiu, jkjaks, d, 
//asdashh*hiu*jkjaks*d

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM