不可變字符串String與可變字符串StringBuilder、StringBuffer使用詳解


String字符串

char類型只能表示一個字符,而String可以表示字符串,也就是一個字符序列。但String不是基本類型,而是一個定義好的類,是一個引用類型。在Java中,可以將字符串直接量賦給String類型變量,也可以采用new String(parameter)的形式來創建字符串。

String str = "This is String”; //用字符串直接量賦值
String str = new String("Create a String through the Constructor"); //String的構造器來創建字符串

這里表示引用變量str,引用一個內容為This is String 的字符串對象。 但通常情況下,可直接稱str變量是一個字符串,無須過於強調細節。

字符串特點:String類是不可變類,並且被final修飾,無法繼承。 字符串對象都是不可變對象,所以對字符串進行操作時,都是返回新的字符串對象,原有字符串不會改變。

字符串在程序設計中用得非常頻繁,所以掌握String字符串的常用方法是很有必要的。例如:

String普通方法

length()        //返回字符串中的字符數,即字符串長度。
charAt(int index) //根據索引位置,返回對應字符。
toLowerCase()    //把字符串中所有字母字符變成小寫。
toUpperCase()     //把字符串中所有字母字符變成大寫。
toCharArray()     //把字符串轉成字符數組,即一個字符對應一個字符數組元素。
trim()            //消除字符串的兩邊空白字符。
        String s = "ABCDEF";
        System.out.println(s.length());  //6
        System.out.println(s.charAt(0)); //索引位置0是 A
        String lowerCase = s.toLowerCase();
        System.out.println(lowerCase); //abcdef
        char[] ch = s.toCharArray();
        System.out.println(ch[0]); // A
        System.out.println("  ABC ".trim()); //ABC

 String比較方法

equals(Object anObject)           //判斷當前字符串對象與指定對象是否相等。

equalsIgnoreCase(String anotherString) //判斷當前字符串對象與指定String 對象是否相等,忽略大小寫。

compareTo(String anotherString)        //按字典順序比較兩個字符串。

compareToIgnoreCase(String str)     //按字典順序比較兩個字符串,忽略大小寫 

boolean startsWith(String prefix)    //判斷是否以指定字符串作為前綴

boolean startsWith(String prefix, int toffset) //從指定的索引處開始,判斷是否以指定字符串作為前綴

boolean endsWith(String suffix)     //當前字符串是否以指定字符串作為后綴。

contains(CharSequence s)         //如果包含指定字符串,則返回 true。否則false

注意:比較兩個字符串內容是否相等時,很多人都會用 ==操作符來比較,但這是錯的,下面說一下它們的區別。

==操作符和equals方法的區別

操作符==比較的是變量值是否相同,因為字符串是引用類型,所以操作符==只能檢測兩個字符串是否指向同一個引用(對象地址),但無法檢測字符串對象的內容。操作符==只能用於判斷基本類型以及引用類型是否為null。

要判斷兩個字符串變量是否相同,應該使用equals()方法來判斷。兩個對象指向同一引用,則說明內容相等。否則開始循環比較字符串內容。String的equals()方法實現細節:

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
        String s = "This is String";
        String s1 = s + ""; //產生一個新字符串
        System.out.println(s == s1); //兩個字符串對象非同一個引用,返回false
        System.out.println(s.equals(s1)); //兩個字符串對象的內容相等,返回true

總結一下就是:操作符==是直接比較變量的值。若是引用類型變量,則比較引用地址是否相同。而equals()方法是比較引用對象中的內容。

演示其他比較方法

        String s = "hello world";
        System.out.println(s.equalsIgnoreCase("HELLO WORLD")); //忽略大小寫,比較字符串內容。true
        //輪流比較字符,字符不相等時,返回字符相減結果:e - a = 4 [69- 65]
        System.out.println(s.compareTo("hallo world")); 
        //判斷前綴
        System.out.println(s.startsWith("hello")); //true
        //判斷后綴
        System.out.println(s.endsWith("worlds")); // false
        //是否包含指定字符串
        System.out.println(s.contains("lo wor")); //空白字符串也屬於字符,別忽略了

除此之外,還有截取子字符串substring()、切割字符串split()、根據索引找字符串indexOf()、lastIndexOf()以及替換相應字符串replace()等等方法。若要了解更多方法,可查閱API。

 

轉換字符串 

有時候,我們需要將某個類型轉成字符串來進行操作。例如將數值類型轉成字符串,可以很快判斷是幾位數,可以快速判斷是否是回文數。

方式有兩種:采用操作符+拼接成字符串;通過靜態方法valueOf(parameter)將相關類型轉成對應字符串。

        String s1 = String.valueOf(123);
        String s2 = 123 +"";

采用操作符+直接轉成字符串是最簡潔、最方便的。

 

 字符串直接量與new String()的區別

        String s1 = "ABC";
        String s2 = new String(s1); //等價於 new String("ABC");
        String s3 = s1 + "";
        System.out.println(s1 == s2); //false
        System.out.println(s1 == s3); //false

字符串直接量是一個字符串對象,而new String(s1)會構建一個同類型但不同內存空間的字符串對象。簡單來說就是,兩者沒有指向同一個引用。所以操作符==判斷為false。

s3 = s1 + ""; 這一段是運行時對字符串變量s1進行拼接,所以會產生一個新的字符串對象。所以為false。

關於對字符串直接量拼接是否相等同內容字符串

如果直接對字符串直接量進行拼接,而非采用變量形式拼接字符串,比較結果又會不同。

        String c = "C";
        String s1 = "ABC";
        String s2 = "AB" + c; 
        String s3 = "A" + "B" + "C";
        System.out.println(s1 == s2); //false
        System.out.println(s1 == s3); //true

因為字符串是常量,所以創建“ABC”這個字符串時,會放在常量池中。 但s2指向的字符串對象引用是到運行時才會確定, 所以會導致創建一個新字符串對象。而s3是以字符串直接量來進行拼接,這些字符串在編譯時就能確定下來,編譯器就在常量池查找是否存在相同的字符串。若已存在,指向同一個字符串對象,否則,另外創建字符串。

 

除了操作符==判斷引用地址外,可以使用System.identityHashcode() 查看內存地址是否相同,identityHashcode() 是根據內存地址生成的哈希值。

 

可變字符串StringBuilder、StringBuffer

String是不可變類,字符串都是常量,例如“ABC”會被存儲在常量池中。對字符串進行任何更改操作都會產生新的String對象。而StringBuilder與StringBuffer是可變類,它們的字符串對象可以更改,對可變字符串的操作不會生成新的對象,即對同一個字符串對象操作。

StringBuilder、StringBuffer創建字符串

        StringBuilder sb = new StringBuilder(); //空字符串
        StringBuilder sb1 = new StringBuilder("字符串"); //以String對象作為參數構建字符串

StringBuilder與StringBuffer構建可變字符串對象都是通過new操作符調用構造方法,不能直接像String一樣接收字符串直接量。

StringBuilder和StringBuffer的使用方式一模一樣,兩者只需要修改一下類名就可以無縫切換。兩者的區別是StringBuilder應用於單線程環境,而StringBuffer應用於多線程環境。所以接下來只以StringBuilder作為示例。 

可變字符串的常用方法(增刪改查)

        append(data)        //將給定數據作為字符串追加到可變字符串尾部
        insert(offset, data)      //將給定數據作為字符串追加到指定的偏移位置
        delete(start, end);       //刪除start 到 end -1 的字符
        replace(start, end, str)  //替換start 到 end -1 的字符
        reverse();            //將該字符串進行倒置
        sb.setCharAt(index, ch);; //設置 index 處的字符為給定字符
        StringBuilder sb = new StringBuilder(); //構建空的可變字符串
        sb.append("String is changed");
        System.out.println(sb); //原字符串對象內容被改變 String is changed
        //在下標0處插入123
        sb.insert(0, 123);
        System.out.println(sb); //123String is changed
        //刪除 sb字符串的后面7位字符
        sb.delete(sb.length() - 7, sb.length());
        System.out.println(sb); //123String is 
        //替換前三位字符
        sb.replace(0, 3, "!!!");
        System.out.println(sb); //!!!String is 
        //翻轉sb字符串
        sb.reverse();
        System.out.println(sb); // si gnirtS!!!
        //設置某個下標的字符內容
        sb.setCharAt(0,'A');
        System.out.println(sb); //Asi gnirtS!!!

可以看到,對可變字符串作出任何更改操作,都會對其字符串對象進行操作。 相比於String,若是需要大量使用字符串的場景,建議采用可變字符串,可以節省很多內存空間。

使用可變字符串的場景

1.將數組內容轉成字符串

    public static String toStringWithArray(int[] arr) {
        StringBuilder sb = new StringBuilder("[");
        for(int i = 0; i < arr.length; i++) {
            if(i != arr.length -1) {
                sb.append(arr[i] + ", ");
            }else {
                sb.append(arr[i] + "]");
            }
        }
        return sb.toString();
    }

如果不采用可變字符串,那么在拼接字符串過程中,會產生很多用不到的字符串對象,很浪費內存空間。

 

凡是需要大量拼接字符串的地方,都應該盡量使用可變字符串來完成,因為效率高,而且不占內存空間。

 


免責聲明!

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



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