1. 程式人生 > WINDOWS開發 >常用API - 字串

常用API - 字串

String類

java.lang.String類代表字串

Java 程式中的所有字串字面值(如 "abc" )都作為此類的例項實現。

特點

  • 字串的內容不可變!!
  • 因為 String 物件是不可變的,所以可以共享。
  • 字串效果上相當於是char[]字元陣列,但底層原理是byte[]位元組陣列(JDK9)

構造方法

構造方法 說明
String() * 初始化一個新建立的 String 物件,使其表示一個空字元序列。
String(byte[] bytes) * 通過使用平臺的預設字符集解碼指定的 byte 陣列,構造一個新的 String。
String(char[] value) * 分配一個新的 String,使其表示字元陣列引數中當前包含的字元序列。
String(String original) 初始化一個新建立的 String 物件,使其表示一個與引數相同的字元序列;換句話說,新建立的字串是該引數字串的副本。
String(byte[] bytes,int offset,int length) 通過使用平臺的預設字符集解碼指定的 byte 子陣列,構造一個新的 String。
String(byte[] bytes,Charset charset) 通過使用指定的 charset 解碼指定的 byte 陣列,構造一個新的 String。
String(byte[] bytes,int length,Charset charset) 通過使用指定的 charset 解碼指定的 byte 子陣列,構造一個新的 String。
String(byte[] bytes,String charsetName) 通過使用指定的字符集解碼指定的 byte 子陣列,構造一個新的 String。
String(byte[] bytes,String charsetName) 通過使用指定的 charset 解碼指定的 byte 陣列,構造一個新的 String。
String(char[] value,int count) 分配一個新的 String,它包含取自字元陣列引數一個子陣列的字元。
String(int[] codePoints,int count) 分配一個新的 String,它包含 Unicode 程式碼點陣列引數一個子陣列的字元。
String(StringBuffer buffer) * 分配一個新的字串,它包含字串緩衝區引數中當前包含的字元序列。
String(StringBuilder builder) * 分配一個新的字串,它包含字串生成器引數中當前包含的字元序列。
package com;

public class StringTest {
    public static void main(String[] args) {
        // 常見建立字串的3+1的方式
        String str1 = new String();
        System.out.println("第一種無參構造方法建立字串:"+str1);

        char[] array = {‘A‘,‘B‘,‘C‘};
        String str2 = new String(array);
        System.out.println("第二種傳入字元陣列建立字串:"+str2);

        byte[] array2 = {65,66,67};
        String str3 = new String(array2);
        System.out.println("第三種傳入位元組陣列建立字串:"+str3);

        String str = "hello";
        System.out.println("直接建立字串:"+str);
    }
}

注意

  • 直接用雙引號建立的字串,JVM會自動將它new成字串物件

字串常量池

程式當中直接寫上雙引號的字串,存在字串常量池中

package com;

public class StringPool {
    public static void main(String[] args) {
        String str1 = "123";
        String str2 = "123";

        char[] charArray = {‘1‘,‘2‘,‘3‘};
        String str3 = new String(charArray);

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

結果

true
false
false

示意圖

技術分享圖片

注意

  • 對於基本型別 --> 兩個等號是比較【數值】是否相等
  • 對於引用型別 --> 兩個等號是比較【地址值】是否相等
  • 直接用雙引號建立的字串會先到常量池看存不存在,字串共享
  • 使用new建立的字串與常量池無關,會在堆中開闢新的空間

常用方法

方法摘要 描述
int length() 返回此字串的長度。
boolean equals(Object anObject) 將此字串與指定的物件比較。 (只有引數是同類型且內容相同才返回true)
boolean equalsIgnoreCase(String anotherString) 將此 String 與另一個 String 比較,不考慮大小寫。
char charAt(int index) 返回指定索引處的 char 值。
String concat(String str) 將指定字串連線到此字串的結尾。
int indexOf(String str) 返回指定子字串在此字串中第一次出現處的索引。
String substring(int beginIndex) 返回一個新的字串,它是此字串的一個子字串。
String substring(int beginIndex,int endIndex) 返回一個新字串,它是此字串的一個子字串。(左閉右開)
char[] toCharArray() 將此字串轉換為一個新的字元陣列。
byte[] getBytes() 使用平臺的預設字符集將此 String 編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。
byte[] getBytes(Charset charset) 使用給定的 charset 將此 String 編碼到 byte 序列,並將結果儲存到新的 byte 陣列。
byte[] getBytes(String charsetName) 使用指定的字符集將此 String 編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。
String replace(char oldChar,char newChar) 返回一個新的字串,它是通過用 newChar 替換此字串中出現的所有 oldChar 得到的。
String replace(CharSequence target,CharSequence replacement) 使用指定的字面值替換序列替換此字串所有匹配字面值目標序列的子字串。
String replaceFirst(String regex,String replacement) 使用給定的 replacement 替換此字串匹配給定的正則表示式的第一個子字串。
String replaceAll(String regex,String replacement) 使用給定的 replacement 替換此字串所有匹配給定的正則表示式的子字串。
String trim() 返回字串的副本,忽略前導空白和尾部空白。
String[] split(String regex) 根據給定正則表示式的匹配拆分此字串。
String[] split(String regex,int limit) 根據匹配給定的正則表示式來拆分此字串。
boolean endsWith(String suffix) 測試此字串是否以指定的字尾結束。
boolean startsWith(String prefix) 測試此字串是否以指定的字首開始。
boolean startsWith(String prefix,int toffset) 測試此字串從指定索引開始的子字串是否以指定字首開始。
int compareTo(String anotherString) 按字典順序比較兩個字串。
int compareToIgnoreCase(String str) 按字典順序比較兩個字串,不考慮大小寫。
boolean contains(CharSequence s) 當且僅當此字串包含指定的 char 值序列時,返回 true。

查詢方法

查詢方法 描述
int indexOf(int ch) 返回指定字元在此字串中第一次出現處的索引。
int indexOf(int ch,int fromIndex) 返回在此字串中第一次出現指定字元處的索引,從指定的索引開始搜尋。
int indexOf(String str) 返回指定子字串在此字串中第一次出現處的索引。
int indexOf(String str,int fromIndex) 返回指定子字串在此字串中第一次出現處的索引,從指定的索引開始。
int lastIndexOf(int ch) 返回指定字元在此字串中最後一次出現處的索引。
int lastIndexOf(int ch,int fromIndex) 返回指定字元在此字串中最後一次出現處的索引,從指定的索引處開始進行反向搜尋。
int lastIndexOf(String str) 返回指定子字串在此字串中最右邊出現處的索引。
int lastIndexOf(String str,int fromIndex) 返回指定子字串在此字串中最後一次出現處的索引,從指定的索引開始反向搜尋。

indexOf 和 lastIndexOf的多種過載方法

轉換方法

轉換方法 描述
String toLowerCase() 使用預設語言環境的規則將此 String 中的所有字元都轉換為小寫。
String toLowerCase(Locale locale) 使用給定 Locale 的規則將此 String 中的所有字元都轉換為小寫。
String toUpperCase() 使用預設語言環境的規則將此 String 中的所有字元都轉換為大寫。
String toUpperCase(Locale locale) 使用給定 Locale 的規則將此 String 中的所有字元都轉換為大寫。
static String valueOf(boolean b) 返回 boolean 引數的字串表示形式。
static String valueOf(char c) 返回 char 引數的字串表示形式。
static String valueOf(char[] data) 返回 char 陣列引數的字串表示形式。
static String valueOf(char[] data,int count) 返回 char 陣列引數的特定子陣列的字串表示形式。
static String valueOf(double d) 返回 double 引數的字串表示形式。
static String valueOf(float f) 返回 float 引數的字串表示形式。
static String valueOf(int i) 返回 int 引數的字串表示形式。
static String valueOf(long l) 返回 long 引數的字串表示形式。
static String valueOf(Object obj) 返回 Object 引數的字串表示形式。
char[] toCharArray() 將此字串轉換為一個新的字元陣列。
byte[] getBytes() 使用平臺的預設字符集將此 String 編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。

?

其他方法

其他方法 描述
String intern() 返回字串物件的規範化表示形式。
boolean isEmpty() 當且僅當 length() 為 0 時返回 true。
int codePointAt(int index) 返回指定索引處的字元(Unicode 程式碼點)。
int codePointBefore(int index) 返回指定索引之前的字元(Unicode 程式碼點)。
int codePointCount(int beginIndex,int endIndex) 返回此 String 的指定文字範圍中的 Unicode 程式碼點數。
boolean contentEquals(CharSequence cs) 將此字串與指定的 CharSequence 比較。
boolean contentEquals(StringBuffer sb) 將此字串與指定的 StringBuffer 比較。
static String copyValueOf(char[] data) 返回指定陣列中表示該字元序列的 String。
static String copyValueOf(char[] data,int count) 返回指定陣列中表示該字元序列的 String。
static String format(Locale l,String format,Object... args) 使用指定的語言環境、格式字串和引數返回一個格式化字串。
static String format(String format,Object... args) 使用指定的格式字串和引數返回一個格式化字串。
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin) 將字元從此字串複製到目標字元陣列。
int hashCode() 返回此字串的雜湊碼。
boolean matches(String regex) 告知此字串是否匹配給定的正則表示式。
int offsetByCodePoints(int index,int codePointOffset) 返回此 String 中從給定的 index 處偏移 codePointOffset 個程式碼點的索引。
boolean regionMatches(boolean ignoreCase,int toffset,String other,int ooffset,int len) 測試兩個字串區域是否相等。
boolean regionMatches(int toffset,int len) 測試兩個字串區域是否相等。
CharSequence subSequence(int beginIndex,int endIndex) 返回一個新的字元序列,它是此序列的一個子序列。

案例

package com;

/**
 * equals方法的使用
 * equalsIgnoreCase 忽略大小寫的比較
 */
public class StringEquals {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        char[] array = {‘H‘,‘e‘,‘l‘,‘o‘};
        String str3 = new String(array);

        System.out.println(str1.equals(str3));
        System.out.println(str2.equals(str3));
        System.out.println(str3.equals("Hello"));
        System.out.println("Hello".equals(str3));
        // 推薦常量字串寫在前面。變數寫前面可能會出現空指標異常

        System.out.println("=============");
        String str4 = "hello";
        System.out.println(str3.equals(str4));
        // 忽略大小寫
        System.out.println(str3.equalsIgnoreCase(str4));

    }
}

注意事項

  • 任何物件都可以用Object進行接收
  • equals方法具有對稱性!即 a.equals(b)b.equals(a)效果一樣
  • 如果一個常量和一個變數比較,推薦把常量字串寫在前面!
package com;

/**
 * length() 返回長度
 * concat 拼接
 * charAt 獲取指定索引位置的單個字元
 * indexOf 查詢首次出現的索引位置,無返回-1
 */
public class StringGet {
    public static void main(String[] args) {
        System.out.println("Hello world".length());

        // 拼接字串 (String不可變!!)
        String str1 = "Hello";
        String str2 = "World";
        String str3 = str1.concat(str2);
        System.out.println(str1); // 原封不動
        System.out.println(str2); // 原封不動
        System.out.println(str3); // 新的字串

        // 獲取指定索引位置的單個字元
        System.out.println("Hello在0號索引位置的字元是:"+"Hello".charAt(0));
        System.out.println("Hello在4號索引位置的字元是:"+"Hello".charAt(4));

        // 查詢引數字串在原字串當中出現的第一次索引位置
        System.out.println();
        String strA = "Hello World Hello1";
        System.out.println(strA.indexOf("hello")); // 查不到返回 -1
        System.out.println(strA.indexOf("Hello1"));// 首次出現的索引

    }
}
package com;

/**
 * 字元的擷取方法
 * substring(int index)
 * substring(int begin,int end) 【b,n)左閉右開
 *
 */
public class StringSub {
    public static void main(String[] args) {
        String str1 = "HelloWorld";
        String str2 = str1.substring(5);
        // 字串不能發生改變,每當對原值操作就是生產新的字串
        System.out.println(str1);
        System.out.println(str2);

        String str3 = str1.substring(4,7);
        // 左閉右開
        System.out.println(str3);

    }
}
package com;

/**
 * 轉換相關的方法
 * toCharArray[] 將當前字串拆分為字元陣列
 * getBytes() 獲得當前字串的底層位元組陣列
 * replace替換
 * valueOf 轉換成字串
 *
 */
public class StringConvert {
    public static void main(String[] args) {
        char[] chars = "Hello".toCharArray();
        System.out.println(chars[0]);
        System.out.println(chars.length);
        System.out.println("===========");

        // IO經常用的位元組流寫入
        byte[] bytes = "abc".getBytes();
        for (byte b : bytes) {
            System.out.print(b + "\t");
        }
        System.out.println();

        String str1 = "Hi boy";
        String str2 = str1.replace("boy","girl");
        System.out.println(str1);
        System.out.println(str2);
        System.out.println("===========");
        
        // 八大基本資料型別轉換為字串
        int num = 123;
        double d = 999.999;
        boolean b = false;
        char ch = ‘a‘;

        System.out.println(String.valueOf(num));
        System.out.println(String.valueOf(d));
        System.out.println(String.valueOf(b));
        System.out.println(String.valueOf(ch));
        
    }
}
package com;

/**
 * 分割方法split
 * String[] split(String regex)
 * split 的引數 regex是一個正則表示式
 * 英文句點“.” 寫成“\\.”
 */
public class StringSplit {
    public static void main(String[] args) {
        String str1 = "1,2,3,4,5";
        System.out.println(str1);
        String[] array1 = str1.split(",");
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        System.out.println();

        // 特殊!!使用英文句號時(.) 需要加兩個反斜槓
        String str2 = "x.y.z";
        //String[] array2 = str2.split("."); // 直接用英文點不行
        String[] array2 = str2.split("\\.");
        System.out.println("長度為:" + array2.length);
        for (String s : array2) {
            System.out.print(s + "\t");
        }

    }
}

練習

  1. 定義一個方法,吧陣列{1,3}按指定格式拼接成一個字串。格式參照如下;[word1#word2$word3]
package com.practise;

/**
 * 定義一個方法,吧陣列{1,3}按指定格式拼接成一個字串。
 * 格式參照如下;[word1#word2$word3]
 */
public class StringPractise {
    public static void main(String[] args) {
        int[] nums = {1,3};
        System.out.println(fromArrayToString(nums));
    }

    public static String fromArrayToString(int[] array) {
        String result = "[";
        for (int i = 0; i < array.length; i++) {
            if (i != array.length - 1) {
                result += "word" + array[i] + "#";
            } else {
                result += "word" + array[i];
            }
        }
        result += "]";
        return result;
    }
}

  1. 鍵盤輸入一個字串,並且統計其中各種字元出現的次數。

    • 種類有:大寫字母、小寫字母、數字、其他
    package com.practise;
    
    import java.util.Scanner;
    
    /**
     * 鍵盤輸入一個字串,並且統計其中各種字元出現的次數。
     * 種類有:大寫字母、小寫字母、數字、其他
     */
    public class StringPractise2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.print("請輸入一個字串:");
            String str = sc.nextLine();
            char[] chars = str.toCharArray();
            int[] count = {0,};
            for (char c : chars) {
                if (c >= ‘A‘ && c <= ‘Z‘) {
                    count[0]++;
                } else if (c >= ‘a‘ && c <= ‘z‘) {
                    count[1]++;
                } else if (c >= ‘0‘ && c <= ‘9‘) {
                    count[2]++;
                } else {
                    count[3]++;
                }
            }
    
            System.out.print("大寫字母、小寫字母、數字、其他依次出現次數:");
            for (int i : count) {
                System.out.print(i + "\t");
            }
        }
    
    }
    
    

StringBuilder類

字串拼接問題

由於String類的物件內容不可改變,所以每當進行字串拼接時,總是會在記憶體中建立一個新的物件。例如:

public class StringDemo {
    public static void main(String[] args) {
        String s = "Hello";
        s += "World";
        System.out.println(s);
    }
}

在API中對String類有這樣的描述:字串是常量,它們的值在建立後不能被更改。

根據這句話分析我們的程式碼,其實總共產生了三個字串,即"Hello""World""HelloWorld"

引用變數s首先指向Hello物件,最終指向拼接出來的新字串物件,即HelloWord

由此可知,如果對字串進行拼接操作,每次拼接,都會構建一個新的String物件,既耗時,又浪費空間。

為了解決這一問題,可以使用java.lang.StringBuilder類。

StringBuilder概述

查閱java.lang.StringBuilder的API,StringBuilder又稱為可變字元序列,它是一個類似於 String 的字串緩衝區

通過某些方法呼叫可以改變該序列的長度和內容。

原來StringBuilder是個字串的緩衝區,即它是一個容器,容器中可以裝很多字串。並且能夠對其中的字串進行各種操作。

它的內部擁有一個數組用來存放字串內容,進行字串拼接時,直接在陣列中加入新內容。

StringBuilder會自動維護陣列的擴容。原理如下圖所示:(預設16字元空間,超過自動擴充)

構造方法

根據StringBuilder的API文件,常用構造方法有2個:

  • public StringBuilder():構造一個空的StringBuilder容器。
  • public StringBuilder(String str):構造一個StringBuilder容器,並將字串新增進去。
方法 描述
StringBuilder() 構造一個不帶任何字元的字串生成器,其初始容量為 16 個字元
StringBuilder(int capacity) 構造一個不帶任何字元的字串生成器,其初始容量由 capacity 引數指定。
StringBuilder(CharSequence seq) 構造一個字串生成器,它包含與指定的 CharSequence 相同的字元。
StringBuilder(String str) 構造一個字串生成器,並初始化為指定的字串內容。
package com;

/**
 * 字串緩衝區,可以提高字串的效率
 */
public class StringBuilderTest {
    public static void main(String[] args) {
        // 無參構造
        StringBuilder sb = new StringBuilder();
        System.out.println(sb);
        System.out.println(sb.length());

        // 構造一個字串生成器,並初始化為指定的字串內容。
        StringBuilder sb2 = new StringBuilder("Hello");
        System.out.println(sb2);
    }
}

常用方法

StringBuilder常用的方法有2個:

  • public StringBuilder append(...):新增任意型別資料的字串形式,並返回當前物件自身。
  • public String toString():將當前StringBuilder物件轉換為String物件。

append方法

append方法具有多種過載形式,可以接收任意型別的引數。任何資料作為引數都會將對應的字串內容新增到StringBuilder中。例如:

package com;

/**
 * 常用方法
 * append 新增任意型別資料的字串形式,並返回當前物件自身
 * 可鏈式新增!sb.append("hello").append("world");
 */
public class StringBuilderTest {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println("呼叫append方法前,sb的值:" + sb);
        sb.append("world");
        System.out.println("呼叫append方法後,sb的值:" + sb);


        StringBuilder builder = new StringBuilder();
        // 可以新增 任何型別
        builder.append("hello ");
        builder.append("world ");
        builder.append(true);
        builder.append(100);
        // 鏈式程式設計
        builder.append("\n---------\n").append("world ").append(true).append(100);
        System.out.println("builder:"+builder);
    }
}

備註:StringBuilder已經覆蓋重寫了Object當中的toString方法。

toString方法

通過toString方法,StringBuilder物件將會轉換為不可變的String物件。如:

package com;

/**
 * StringBuilder 和 String 之間的轉換
 * String -> StringBuilder  : new StringBuilder("字串")
 * StringBuilder -> String  : toString()
 */
public class StringBuilderTest2 {
    public static void main(String[] args) {
        String str = "hello";
        System.out.println(str);

        StringBuilder sb = new StringBuilder(str);
        sb.append(" world");
        System.out.println(sb);

        String s = sb.toString();
        System.out.println(s);

    }
}

方法自查

方法 描述
int capacity() 返回當前容量。
char charAt(int index) 返回此序列中指定索引處的 char 值。
StringBuilder reverse() 將此字元序列用其反轉形式取代。
StringBuilder deleteCharAt(int index) 移除此序列指定位置上的 char。
StringBuilder delete(int start,int end) 移除此序列的子字串中的字元。
StringBuilder append(int i) 將 int 引數的字串表示形式追加到此序列。
StringBuilder append(boolean b) 將 boolean 引數的字串表示形式追加到序列。
StringBuilder append(char c) 將 char 引數的字串表示形式追加到此序列。
StringBuilder append(char[] str) 將 char 陣列引數的字串表示形式追加到此序列。
StringBuilder append(char[] str,int offset,int len) 將 char 陣列引數的子陣列的字串表示形式追加到此序列。
StringBuilder append(CharSequence s) 向此 Appendable 追加到指定的字元序列。
StringBuilder append(CharSequence s,int start,int end) 將指定 CharSequence 的子序列追加到此序列。
StringBuilder append(double d) 將 double 引數的字串表示形式追加到此序列。
StringBuilder append(float f) 將 float 引數的字串表示形式追加到此序列。
StringBuilder append(long lng) 將 long 引數的字串表示形式追加到此序列。
StringBuilder append(Object obj) 追加 Object 引數的字串表示形式。
StringBuilder append(String str) 將指定的字串追加到此字元序列。
StringBuilder append(StringBuffer sb) 將指定的 StringBuffer 追加到此序列。
StringBuilder appendCodePoint(int codePoint) 將 codePoint 引數的字串表示形式追加到此序列。
int codePointAt(int index) 返回指定索引處的字元(統一程式碼點)。
int codePointBefore(int index) 返回指定索引前的字元(統一程式碼點)。
int codePointCount(int beginIndex,int endIndex) 返回此序列指定文字範圍內的統一程式碼點。
void ensureCapacity(int minimumCapacity) 確保容量至少等於指定的最小值。
void getChars(int srcBegin,int dstBegin) 將字元從此序列複製到目標字元陣列 dst。
int indexOf(String str) 返回第一次出現的指定子字串在該字串中的索引。
int indexOf(String str,int fromIndex) 從指定的索引處開始,返回第一次出現的指定子字串在該字串中的索引。
StringBuilder insert(int offset,boolean b) 將 boolean 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,char c) 將 char 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,char[] str) 將 char 陣列引數的字串表示形式插入此序列中。
StringBuilder insert(int index,char[] str,int len) 將陣列引數 str 子陣列的字串表示形式插入此序列中。
StringBuilder insert(int dstOffset,CharSequence s) 將指定 CharSequence 插入此序列中。
StringBuilder insert(int dstOffset,CharSequence s,int start,int end) 將指定 CharSequence 的子序列插入此序列中。
StringBuilder insert(int offset,double d) 將 double 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,float f) 將 float 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,int i) 將 int 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,long l) 將 long 引數的字串表示形式插入此序列中。
StringBuilder insert(int offset,Object obj) 將 Object 引數的字串表示形式插入此字元序列中。
StringBuilder insert(int offset,String str) 將字串插入此字元序列中。
int lastIndexOf(String str) 返回最右邊出現的指定子字串在此字串中的索引。
int lastIndexOf(String str,int fromIndex) 返回最後一次出現的指定子字串在此字串中的索引。
int length() 返回長度(字元數)。
int offsetByCodePoints(int index,int codePointOffset) 返回此序列中的一個索引,該索引是從給定 index 偏移 codePointOffset 個程式碼點後得到的。
StringBuilder replace(int start,int end,String str) 使用給定 String 中的字元替換此序列的子字串中的字元。
void setCharAt(int index,char ch) 將給定索引處的字元設定為 ch。
void setLength(int newLength) 設定字元序列的長度。
CharSequence subSequence(int start,int end) 返回一個新字元序列,該字元序列是此序列的子序列。
String substring(int start) 返回一個新的 String,它包含此字元序列當前所包含字元的子序列。
String substring(int start,int end) 返回一個新的 String,它包含此序列當前所包含字元的子序列。
String toString() 返回此序列中資料的字串表示形式。
void trimToSize() 嘗試減少用於字元序列的儲存空間。