天天看點

java學習筆記(8)——String類詳解java學習筆記(8)——String類詳解5.常用方法:

java學習筆記(8)——String類詳解

1.概述

String:字元串,使用一對""引起來表示。

  1. String聲明為final的,不可被繼承
  2. String實作了Serializable接口:表示字元串是支援序列化的。實作了Comparable接口:表示String可以比較大小
  3. String内部定義了final char[] value用于存儲字元串資料
  4. 通過字面量的方式(差別于new給一個字元串指派,此時的字元串值聲明在字元串常量池中)。
  5. 字元串常量池中是不會存儲相同内容(使用String類的equals()比較,傳回true)的字元串的。

2.String的不可變性

2.1 說明

  1. 當對字元串重新指派時,需要重寫指定記憶體區域指派,不能使用原有的value進行指派。
  2. 當對現的字元串進行連接配接操作時,也需要重新指定記憶體區域指派,不能使用原有的value進行指派。
  3. 當調用String的replace()方法修改指定字元或字元串時,也需要重新指定記憶體區域指派,不能使用原有的value進行指派。
public void test1(){
        String s1 = "abc";//字面量的定義方式
        String s2 = "abc";
        s1 = "hello";

        System.out.println(s1 == s2);//比較s1和s2的位址值

        System.out.println(s1);//hello
        System.out.println(s2);//abc

        System.out.println("*****************");

        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println(s2);

        System.out.println("*****************");

        String s4 = "abc";
        String s5 = s4.replace('a', 'm');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc

    }
           
java學習筆記(8)——String類詳解java學習筆記(8)——String類詳解5.常用方法:

3.String執行個體化的不同方式

3.1 方式說明

  • 方式一:通過字面量定義的方式
  • 方式二:通過new + 構造器的方式
public void test2(){
        //通過字面量定義的方式:此時的s1和s2的資料javaEE聲明在方法區中的字元串常量池中。
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通過new + 構造器的方式:此時的s3和s4儲存的位址值,是資料在堆空間中開辟空間以後對應的位址值。
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");

        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s1 == s4);//false
        System.out.println(s3 == s4);//false
 
        System.out.println("***********************");
        Person p1 = new Person("Tom",12);
        Person p2 = new Person("Tom",12);

        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true

        p1.name = "Jerry";
        System.out.println(p2.name);//Tom
    }
           
  • String s = new String(“abc”);方式建立對象,在記憶體中建立了幾個對象?

    兩個:一個是堆空間中new結構,另一個是char[]對應的常量池中的資料:“abc”

java學習筆記(8)——String類詳解java學習筆記(8)——String類詳解5.常用方法:

4. 字元串拼接方式指派的對比

4.1 說明

  1. 常量與常量的拼接結果在常量池。且常量池中不會存在相同内容的常量。
  2. 隻要其中一個是變量,結果就在堆中。
  3. 如果拼接的結果調用intern()方法,傳回值就在常量池中
@Test
    public void test4(){
        String s1 = "javaEEhadoop";
        String s2 = "javaEE";
        String s3 = s2 + "hadoop";
        System.out.println(s1 == s3);//false

        final String s4 = "javaEE";//s4:常量
        String s5 = s4 + "hadoop";
        System.out.println(s1 == s5);//true

    }

    @Test
    public void test3(){
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false

        String s8 = s6.intern();//傳回值得到的s8使用的常量值中已經存在的“javaEEhadoop”
        System.out.println(s3 == s8);//true


    }
           

5.常用方法:

  1. int length():傳回字元串的長度: return value.length
  2. char charAt(int index): 傳回某索引處的字元return value[index]
  3. boolean isEmpty():判斷是否是空字元串:return value.length == 0
  4. String toLowerCase():使用預設語言環境,将 String 中的所字元轉換為小寫
  5. String toUpperCase():使用預設語言環境,将 String 中的所字元轉換為大寫
  6. String trim():傳回字元串的副本,忽略前導空白和尾部空白
  7. boolean equals(Object obj):比較字元串的内容是否相同
  8. boolean equalsIgnoreCase(String anotherString):與equals方法類似,忽略大小寫
  9. String concat(String str):将指定字元串連接配接到此字元串的結尾。 等價于用“+”
  10. int compareTo(String anotherString):比較兩個字元串的大小
  11. String substring(int beginIndex):傳回一個新的字元串,它是此字元串的從beginIndex開始截取到最後的一個子字元串。
  12. String substring(int beginIndex, int endIndex) :傳回一個新字元串,它是此字元串從beginIndex開始截取到endIndex(不包含)的一個子字元串。
public void test2() {
        String s1 = "HelloWorld";
        String s2 = "helloworld";
        System.out.println(s1.equals(s2));
        System.out.println(s1.equalsIgnoreCase(s2));

        String s3 = "abc";
        String s4 = s3.concat("def");
        System.out.println(s4);

        String s5 = "abc";
        String s6 = new String("abe");
        System.out.println(s5.compareTo(s6));//涉及到字元串排序

        String s7 = "北京尚矽谷教育";
        String s8 = s7.substring(2);
        System.out.println(s7);
        System.out.println(s8);

        String s9 = s7.substring(2, 5);
        System.out.println(s9);
    }

    @Test
    public void test1() {
        String s1 = "HelloWorld";
        System.out.println(s1.length());
        System.out.println(s1.charAt(0));
        System.out.println(s1.charAt(9));
//        System.out.println(s1.charAt(10));
//        s1 = "";
        System.out.println(s1.isEmpty());

        String s2 = s1.toLowerCase();
        System.out.println(s1);//s1不可變的,仍然為原來的字元串
        System.out.println(s2);//改成小寫以後的字元串

        String s3 = "   he  llo   world   ";
        String s4 = s3.trim();
        System.out.println("-----" + s3 + "-----");
        System.out.println("-----" + s4 + "-----");
    }
}
           
  1. boolean endsWith(String suffix):測試此字元串是否以指定的字尾結束
  2. boolean startsWith(String prefix):測試此字元串是否以指定的字首開始
  3. boolean startsWith(String prefix, int toffset):測試此字元串從指定索引開始的子字元串是否以指定字首開始
  4. boolean contains(CharSequence s):當且僅當此字元串包含指定的 char 值序列時,傳回 true
  5. int indexOf(String str):傳回指定子字元串在此字元串中第一次出現處的索引
  6. int indexOf(String str, int fromIndex):傳回指定子字元串在此字元串中第一次出現處的索引,從指定的索引開始
  7. int lastIndexOf(String str):傳回指定子字元串在此字元串中最右邊出現處的索引
  8. int lastIndexOf(String str, int fromIndex):傳回指定子字元串在此字元串中最後一次出現處的索引,從指定的索引開始反向搜尋
@Test
public void test3(){
    String str1 = "hellowworld";
    boolean b1 = str1.endsWith("rld");
    System.out.println(b1);

    boolean b2 = str1.startsWith("He");
    System.out.println(b2);

    boolean b3 = str1.startsWith("ll",2);
    System.out.println(b3);

    String str2 = "wor";
    System.out.println(str1.contains(str2));

    System.out.println(str1.indexOf("lol"));

    System.out.println(str1.indexOf("lo",5));

    String str3 = "hellorworld";

    System.out.println(str3.lastIndexOf("or"));
    System.out.println(str3.lastIndexOf("or",6));

    //什麼情況下,indexOf(str)和lastIndexOf(str)傳回值相同?
    //情況一:存在唯一的一個str。情況二:不存在str
}
           

替換:

22. String replace(char oldChar, char newChar):傳回一個新的字元串,它是通過用 newChar 替換此字元串中出現的所 oldChar 得到的。

23. String replace(CharSequence target, CharSequence replacement):使用指定的字面值替換序列 替換此字元串所比對字面值目标序列的子字元串。

24. String replaceAll(String regex, String replacement):使用給定的 replacement 替換此字元串所比對給定的正規表達式的子字元串。

25. String replaceFirst(String regex, String replacement):使用給定的 replacement 替換此字元串比對給定的正規表達式的第一個子字元串。

比對:

26. boolean matches(String regex):告知此字元串是否比對給定的正規表達式。

切片:

27. String[] split(String regex):根據給定正規表達式的比對拆分此字元串。

28. String[] split(String regex, int limit):根據比對給定的正規表達式來拆分此字元串,最多不超過limit個,如果超過了,剩下的全部都放到最後一個元素中。

public void test4(){
        String str1 = "北京尚矽谷教育北京";
        String str2 = str1.replace('北', '東');

        System.out.println(str1);
        System.out.println(str2);


        String str3 = str1.replace("北京", "上海");
        System.out.println(str3);

        System.out.println("*************************");
        String str = "12hello34world5java7891mysql456";
        //把字元串中的數字替換成,,如果結果中開頭和結尾有,的話去掉
        String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$", "");
        System.out.println(string);

        System.out.println("*************************");
        str = "12345";
        //判斷str字元串中是否全部有數字組成,即有1-n個數字組成
        boolean matches = str.matches("\\d+");
        System.out.println(matches);
        String tel = "0571-4534289";
        //判斷這是否是一個杭州的固定電話
        boolean result = tel.matches("0571-\\d{7,8}");
        System.out.println(result);


        System.out.println("*************************");
        str = "hello|world|java";
        String[] strs = str.split("\\|");
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
        System.out.println();
        str2 = "hello.world.java";
        String[] strs2 = str2.split("\\.");
        for (int i = 0; i < strs2.length; i++) {
            System.out.println(strs2[i]);
        }

    }
           

6. String與其它結構的轉換

6.1 與基本資料類型、包裝類之間的轉換

>String --> 基本資料類型、包裝類:調用包裝類的靜态方法:parseXxx(str)
基本資料類型、包裝類 --> String:調用String重載的valueOf(xxx)
           
public void test1(){
        String str1 = "123";
//        int num = (int)str1;//錯誤的
        int num = Integer.parseInt(str1);

        String str2 = String.valueOf(num);//"123"
        String str3 = num + "";

        System.out.println(str1 == str3);
    }

           

6.2 與字元數組之間的轉換

String --> char[]:調用String的toCharArray()

char[] --> String:調用String的構造器

public void test2(){
    String str1 = "abc123";  //題目: a21cb3

    char[] charArray = str1.toCharArray();
    for (int i = 0; i < charArray.length; i++) {
        System.out.println(charArray[i]);
    }

    char[] arr = new char[]{'h','e','l','l','o'};
    String str2 = new String(arr);
    System.out.println(str2);
}
           

6.3 與位元組數組之間的轉換

編碼:String --> byte[]:調用String的getBytes()

解碼:byte[] --> String:調用String的構造器

編碼:字元串 -->位元組 (看得懂 —>看不懂的二進制資料)

解碼:編碼的逆過程,位元組 --> 字元串 (看不懂的二進制資料 —> 看得懂

說明:解碼時,要求解碼使用的字元集必須與編碼時使用的字元集一緻,否則會出現亂碼。

public void test3() throws UnsupportedEncodingException {
    String str1 = "abc123中國";
    byte[] bytes = str1.getBytes();//使用預設的字元集,進行編碼。
    System.out.println(Arrays.toString(bytes));

    byte[] gbks = str1.getBytes("gbk");//使用gbk字元集進行編碼。
    System.out.println(Arrays.toString(gbks));

    System.out.println("******************");

    String str2 = new String(bytes);//使用預設的字元集,進行解碼。
    System.out.println(str2);

    String str3 = new String(gbks);
    System.out.println(str3);//出現亂碼。原因:編碼集和解碼集不一緻!


    String str4 = new String(gbks, "gbk");
    System.out.println(str4);//沒出現亂碼。原因:編碼集和解碼集一緻!


}
           

6.4 與StringBuffer、StringBuilder之間的轉換

String -->StringBuffer、StringBuilder:調用StringBuffer、StringBuilder構造器

StringBuffer、StringBuilder -->String:①調用String構造器;②StringBuffer、StringBuilder的toString()

7 String、StringBuffer、StringBuilder三者的對比

  • String:不可變的字元序列;底層使用char[]存儲
  • StringBuffer:可變的字元序列;線程安全的,效率低;底層使用char[]存儲
  • StringBuilder:可變的字元序列;jdk5.0新增的,線程不安全的,效率高;底層使用char[]存儲

7.1.StringBuffer與StringBuilder的記憶體解析

以StringBuffer為例:

String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底層建立了一個長度是16的數組。
System.out.println(sb1.length());//
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';

StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
           
  • 底層建立了一個長度是16的數組。
  • 問題1. System.out.println(sb2.length());//3
  • 問題2. 擴容問題:如果要添加的資料底層數組盛不下了,那就需要擴容底層的數組。

    預設情況下,擴容為原來容量的2倍 + 2,同時将原數組中的元素複制到新的數組中。

    指導意義:開發中建議大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)

7.2.對比String、StringBuffer、StringBuilder三者的執行效率

從高到低排列:StringBuilder > StringBuffer > String

7.4.StringBuffer、StringBuilder中的常用方法

  • 增:append(xxx)
  • 删:delete(int start,int end)
  • 改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
  • 查:charAt(int n )
  • 插:insert(int offset, xxx)
  • 長度:length();
  • 周遊:for() + charAt() / toString()

備注:本文來自觀看尚矽谷視訊做的筆記。強烈推薦!