JAVA學(xué)習(xí)記錄之String類的常用方法

在編寫程序的過程中,不了避免的要用到字符串,所以String類的常用方法的用法是必須掌握的。學(xué)習(xí)一個類的使用方法最好的措施就是讀JAVA類庫
的官方文檔和閱讀源碼。jdk1.8 api谷歌翻譯中文版下載地址

JDK api 1.8中文版.PNG

  • String類的基本概述
  • 從文檔中可以知道String類屬于java.lang包,所以使用時不用導(dǎo)包,String用final修飾,故不能有子類,繼承了Object類,實(shí)現(xiàn)了接口Serializable,Comparable<String>,CharSequence
  • String類代表字符串。 Java程序中的所有字符串文字(例如"abc" )都被實(shí)現(xiàn)為此類的實(shí)例。字符串不變; 它們的值在創(chuàng)建后不能被更改。 字符串緩沖區(qū)支持可變字符串。 因?yàn)镾tring對象是不可變的,它們可以被共享。即String str = "abc","abc"就是String的一個對象。而且"abc"不能改變,即使對str再次賦值str = "def",也只是將str指向新的字符串,原來的字符串"abc"任然沒有改變,并且變成了內(nèi)存中的垃圾。
  • 字符串常量被放在內(nèi)存的常量池中。當(dāng)創(chuàng)建一個字符串常量后,系統(tǒng)會在常量池中查找是否有與該字符串常量字面值相同的字符串,如果沒有,就在常量池中創(chuàng)建該常量。
  • Java語言為字符串連接運(yùn)算符(+)提供特殊支持,并為其他對象轉(zhuǎn)換為字符串。 字符串連接是通過StringBuilder (或StringBuffer )類及其append方法實(shí)現(xiàn)的。 字符串轉(zhuǎn)換是通過方法toString來實(shí)現(xiàn)。如""+'a'+10將空串""與后面的字符a和整型10相連將變成"a10"。在介紹了后面的String的構(gòu)造方法后將對這一機(jī)制的實(shí)現(xiàn)做進(jìn)一步的描述。
  • 構(gòu)造方法
  • 字符串常量直接賦值
String str = "abc";
String str2 = "abc";
System.out.println(str == str2);

輸出結(jié)果是true。正如概述中所說,通過這種方式賦值給字符串變量(引用類型),字符串常量的字面值就是該變量的實(shí)例對象。在常量池中創(chuàng)建了"abc"后,對于語句2,發(fā)現(xiàn)"abc"已經(jīng)在常量池中存在了,所以就將該"abc"也賦給了str2,所以str和str2指向的是同一個對象,地址值是相同的。這一過程的內(nèi)存分配如圖。


字符串內(nèi)存圖.PNG
  • 空參構(gòu)造
    String()初始化新創(chuàng)建的String對象,使其表示空字符序列。
  • 有參構(gòu)造
    String(String original)
    初始化新創(chuàng)建的String對象,使其表示與參數(shù)相同的字符序列;換句話說,新創(chuàng)建的字符串是參數(shù)字符串的副本。String s1 = new String("abc");
    這個語句是在常量池中創(chuàng)建了常量"abc",然后在堆內(nèi)存中創(chuàng)建了一個字符串對象,將"abc"的值拷貝到這個對象中。所以實(shí)際上是常見了兩個對象,并且將堆內(nèi)存的對象的地址賦給s1。這一過程的內(nèi)存圖如下。
    字符串內(nèi)存圖2.PNG

    String(byte[] bytes)
    通過使用平臺的默認(rèn)字符集解碼指定的字節(jié)數(shù)組來構(gòu)造新的String。通過這個方法可以將數(shù)組轉(zhuǎn)換成字符串。
byte[] arr = {97,98,99};
String str3 = new String(arr);
System.out.println(str3);               //abc

將字符數(shù)組組成字符串,使用的編碼是由平臺的編碼系統(tǒng)決定的。不同于字符的編碼,java的字符編碼是固定的unicode,而組成字符串是將硬盤中的字節(jié)數(shù)據(jù)轉(zhuǎn)到內(nèi)存中,將這些字節(jié)流進(jìn)行編碼,使之成為我們能夠理解的語言,又成為字節(jié)流的解碼過程,這個涉及到輸入輸出流的問題。在以后學(xué)習(xí)后再進(jìn)一步闡述。String(byte[] bytes, int offset, int length)
這個構(gòu)造方法可以選擇從byte數(shù)組中的哪個字節(jié)開始,取幾個字節(jié)構(gòu)成字符串。

byte[] arr2 = {97,98,99,100};
    String str4 = new String(arr2, 1, 3);
    System.out.println(str4);        //bcd

其實(shí)通過源碼可以看到,將整個數(shù)組轉(zhuǎn)化成字符串的構(gòu)造方法底層的實(shí)現(xiàn)其實(shí)就是這個有參構(gòu)造方法,只是對其進(jìn)行了封裝,使我們的使用更加方便了。

public String(byte bytes[]) {
        this(bytes, 0, bytes.length);
    }

Sting (char[] value,int offset,int count)
將指定的字符數(shù)組從offset開始,長度為count的字符元素連綴成字符串。

char[] arr = {'a','b','c'};
String str = new String(arr,1,2);
System.out.println(str);        //bc

以上便是常用的構(gòu)造方法,對于這一部分,通過一個小練習(xí)來加深對字符串概念的理解。

String str = "ab";
String str2 = "abc";
String str3 = str +"c";
System.out.println(str2 == str3);       //false
System.out.println(str2.equals(str3));  //true

前兩條語句很好理解,就是在常量池中創(chuàng)建字符串常量"ab"和"abc"并將他們的地址賦給str和str2,對于第三條語句,就是字符串特有的用過+將字符串與其他數(shù)據(jù)類型拼接成新的字符串。先創(chuàng)建了一個StringBuffer對象,將字符串的值進(jìn)行拼接,在通過toString方法將StringBuffer轉(zhuǎn)化成String,再將新的String對象的地址賦給str3,所以str2和str3的地址值是不一樣,str2對象地址在常量池,而str3對象地址在堆。內(nèi)存圖如圖所示。


字符串拼接內(nèi)存圖.PNG
  • 常用方法
  • char charAt(int index):獲取字符串中指定位置的字符。字符串的索引與數(shù)組的類似,都是從0開始的。這個方法常用來遍歷字符串中的元素。
  • int length():返回字符串的長度
    上面兩個方法常常用來遍歷字符串的元素
String str = "abcd";
for (int i = 0;i<str.length();i++){
        System.out.print(str.charAt(i)+" ");        //a b c d
}
  • boolean equals(String str);判斷兩個字符串是否相等
  • boolean equalsIngnoreCase(String str):不區(qū)分大小寫判斷兩個字符是否相等
  • boolean startWith(String prefix)判斷字符串是否以prefix開始
  • boolean starWith(String prefix , int toffset)判斷字符串從toffset位置算起,是否以prefix開始
  • boolean endWith(String suffix):判斷字符串是否以suffix結(jié)尾
  • boolean contain(CharSequence s)判斷字符串是否包含子串s
    以上方法的測試代碼
String str = "abc";
        String str2 =  "Abc";
        String str3 =  "ab";
        String str4 =  "bc";
        System.out.println(str.equals(str2));           //false
        System.out.println(str.equalsIgnoreCase(str2));//true   不區(qū)分大小寫
        System.out.println(str.startsWith(str3));       //true
        System.out.println(str.endsWith(str4));         //true
        System.out.println(str.contains(str3));         //true
  • boolean isEmpty()判斷字符串是否為空,注意字符串為空串,和字符串引用為空的區(qū)別
String str5 = "";
String str6 = null;
System.out.println(str5.isEmpty()+"   "+str.isEmpty());//true false
System.out.println(str6.isEmpty());     //NullPointerException字符串為空不等于空指針

當(dāng)字符串指針指向?yàn)榭諘r,相當(dāng)于沒有指向?qū)ο螅荒軐ζ湔{(diào)用任何方法,否則會出現(xiàn)空指針異常

  • int indexOf(String str) 返回str子字符串在該字符串中第一次出現(xiàn)的位置
  • int indexOf(String str,int fromIndex) 返回str子字符串在該字符串中從fromIndex開始后第一次出現(xiàn)的位置
  • int indexOf(char ch) 返回ch字符在該字符串中從fromIndex開始扣第一次出現(xiàn)的位置
  • int index(char ch,int fromIndex)返回字符在該字符串中從fromIndex開始后第一次出現(xiàn)的位置
  • int lastIndexOf(String str, int fromIndex)返回從fromIndex開始向前找子字符串str在該字符中第一次出現(xiàn)的位置
  • String substring(int beginIndex, int endIndex)截取從beginIndex開始到endIndex結(jié)束的子串,注意的是這個包含頭不包含尾,即不包含索引endIndex處的字符
    關(guān)于返回字符串索引的位置的方法代碼練習(xí)
public class Demo_String4 {

    public static void main(String[] args) {
        demo1();
        demo2();
        demo3();
        demo4();
    }

    private static void demo4() {
        String str = "abcd";
        System.out.println(str.substring(2, 4));//cd,從指定位置截取字符串到指定位置結(jié)束,包含頭不包含尾
    }

    private static void demo3() {
        String str = "abcde";
        System.out.println(str.indexOf("cd", 1)); // 2,,從指定位置往后找
        
        System.out.println(str.lastIndexOf("bc",4)); //1,從指定位置向前找
    }

    private static void demo2() {
        String str = "abcd";
        int x = str.indexOf('b');       //參數(shù)是int,傳入字符會自動類型提升
        int y = str.indexOf("cd");
        System.out.println(x);          //1
        System.out.println(y);          //2
        System.out.println(str.indexOf("be"));//-1
    }

    private static void demo1() {
        char[] chararry= {'a','b','c'};
        String str = "abc";
        String str2 = "中文字符串";
        
        System.out.println(chararry.length);                    //數(shù)組的length是屬性
        System.out.println(str.length()+"..."+str2.length());   //字符串的length是方法,獲取的是字符的個數(shù),與字符字節(jié)數(shù)無關(guān)
        
        System.out.println(str.charAt(2));  //c
        System.out.println(str.charAt(3));  //StringIndexOutOfBoundsException字符串指針越界異常
    }   
}
  • byte[] getBytes() 將字符串轉(zhuǎn)化成字節(jié)數(shù)組,這個過程又成為編碼過程,將人們理解的語言轉(zhuǎn)化成計(jì)算機(jī)識別的語言
String str = "abcd";
        byte[] arr = str.getBytes();                //編碼:將字符轉(zhuǎn)換成計(jì)算機(jī)能識別的語言
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        
        String str2 = "中文字符串";
        byte[] arr2 = str2.getBytes();
        for (int i = 0; i < arr2.length; i++) {
            System.out.print(arr2[i]+" ");  //-42 -48 -50 -60 -41 -42 -73 -5 -76 -82 
                                            //gbk編碼,一個中文兩個字節(jié),第一個必為負(fù)數(shù)
        }

對于gbk編碼,一個中文由兩個字節(jié)組成,所以一個中文對應(yīng)數(shù)組中的兩個元素,且第一個元素必定為負(fù)數(shù)。

  • char[] toCharArray()將字符串轉(zhuǎn)化成字符數(shù)組,一個字符對應(yīng)一個元素,且這些字符都是由unicode編碼的
  • static String valueOf(char data[])將字符數(shù)組轉(zhuǎn)化成字符串,前面提到一個將字符數(shù)組轉(zhuǎn)化成字符串的構(gòu)造方法,其實(shí)從源碼上看,這個方法就是通過這個構(gòu)造方法實(shí)現(xiàn)的,只不過將其封裝起來,就不需要開發(fā)者自己去調(diào)用這個構(gòu)造方法,這個看似簡單的方法,其實(shí)進(jìn)一步反映了對面對象的思想,就是盡量交由底層去實(shí)現(xiàn),使用者不需自己去實(shí)現(xiàn),只負(fù)責(zé)通過對象調(diào)用這個方法就行了。

通過一個題目了解關(guān)于鏈?zhǔn)骄幊?br> 將一個字符串的首字母大寫,其余變成小寫

public static void main(String[] args) {
        String str2 = "zheSHiYIgecesHi";
        System.out.println(str2.substring(0, 1).toUpperCase().concat(str2.substring(1).toLowerCase()));
    }

代碼中只通過一行代碼就實(shí)現(xiàn)了,通過不斷掉調(diào)用對象的方法實(shí)現(xiàn)。只要一個方法返回的是一個對象,就能不斷的調(diào)用其方法,稱之為鏈?zhǔn)骄幊獭?/p>

  • String replace(char oldChar, char newChar)將字符串中oldChar替換為newChar,如果原字符串中不存在oldChar字符,則不進(jìn)行修改
  • int compareTo(String anotherString)比較兩個字符串的大小。如果兩個字符串的字符序列相等,則返回0;不相等時,從兩個字符第0個字符開始比較,返回第一個不相等的字符差。另一種情況,較長字符串的前面部分恰好是較短額字符串,則返回他們的長度差。
  • String trim()去除字符串兩端的空格,常用語賬號密碼的讀取,因?yàn)閮啥说目崭袢庋垭y以看見,如果在錄入賬號密碼時不去除,常常會產(chǎn)生錯誤。
    public static void main(String[] arg){
        String str = "abcd";
        System.out.println(str.replace('a', 'z'));
        System.out.println(str.replace('c', 'z'));
        
        System.out.println(str.compareTo("abc"));
        
        String str2 = " abc ";
        System.out.println(str2.trim());    //去除兩端空格,應(yīng)用:錄入賬號密碼兩端空格難以識別
        
        System.out.println('中'+0);          //unicode碼表
        System.out.println('文'+0);          //字符串與字節(jié)的轉(zhuǎn)換是系統(tǒng)的碼表,從內(nèi)存到硬盤的編碼
    }

以上就是關(guān)于String類的常用方法。
今天的學(xué)習(xí)的一個比較重要的體會是關(guān)于面向?qū)ο蟮乃枷氲膽?yīng)用。由于之前一直在用C語言,習(xí)慣性的采用面對過程的方法,即很多都自己去實(shí)現(xiàn)每一個步驟,而今天發(fā)現(xiàn)很多簡單的步驟,如調(diào)用另一個方法,在java中都是采取封裝成一個新的方法的形式,這樣使用者就真正的做到,幾乎只需要創(chuàng)建對象,在使用對象的方法就行了,而不用總是通過底層的原理實(shí)現(xiàn)。第二是關(guān)于字節(jié)流,漸漸區(qū)分了字節(jié)流與字符的區(qū)別,字符是一種數(shù)據(jù)類型,而字節(jié)流失一連串的字節(jié)數(shù)據(jù),即一串01數(shù)據(jù),通過不同的編碼可以表示不同的數(shù)據(jù),包括數(shù)字,符號,甚至是其他的視頻,圖像的數(shù)據(jù)。而字節(jié)流的單位通常是自己,即byte,所以getByte方法有稱為編碼過程,就是將數(shù)據(jù)轉(zhuǎn)成01數(shù)據(jù),以字節(jié)為單位存放在數(shù)組中。

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

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

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