String、StringBuffer、StringBuilder詳解


String類

字符串廣泛應用在java編程中,String類在java.lang包中,String類是final修飾的,不能被繼承,String類對象創建后不能修改,由0或多個字符組成,包含在一對雙引號之間。今天來談談String類中一些常用的方法和一些需要注意的點。


構造方法

String共有11種構造方法,下面就不全部舉例了,列出一些常用的構造方法:
1、public String()
無參構造方法,用來創建空字符串的String對象。

String str1 = new String(); 

2、public String(String value)
用已知的字符串value創建一個String對象。

String str2 = new String("qwer"); String str3 = new String(str2); 

3、public String(char[] value)
用字符數組value創建一個String對象。

char[] value = {"a","b","c","d"}; String str4 = new String(value);//相當於String str4 = new String("abcd"); 

4、public String(char chars[], int startIndex, int numChars)
用字符數組chars的startIndex開始的numChars個字符創建一個String對象。

char[] value = {"a","b","c","d"}; String str5 = new String(value, 1, 2);//相當於String str5 = new String("bc"); 

5、public String(byte[] values)
用比特數組values創建一個String對象。

byte[] strb = new byte[]{65,66,67,68}; String str6 = new String(strb);//相當於String str6 = new String("ABCD"); 

6、public String(byte[] values,int startIndex, int numChars)
用字符數組byte的startIndex開始的numChars個字符創建一個String對象。

byte[] strb = new byte[]{65,66,67,68}; String str6 = new String(strb,0,1);//相當於String str6 = new String("A"); 

String類常用方法

1、length()
返回字該字符串的長度

2、charAt(int indext)
求字符串某一位置的字符,index必須>=0並且<= length()-1

3、截取字符串

  • substring(int beginIndex)
    該方法從beginIndex位置起(包含這個位置)到最后截取一個字符串返回。
    [beginIndex,最后]
  • substring(int beginIndex,endIndex)
    該方法從beginIndex位置起(包含這個位置)到endIndex - 1截取一個字符串返回。
    [beginIndex,endIndex - 1]
    例:
String str1 = new String("abcdefgkl"); String str2 = str1.substring(2);//str2 = "cdefgkl" String str3 = str1.substring(2,5);//str3 = "cde" 

4、字符串比較

  • public int compareTo(String anotherString)
    該方法是對字符串內容按字典順序進行大小比較,通過返回的整數值指明當前字符串與參數字符串的大小關系。若當前對象比參數大則返回正整數,反之返回負整數,相等返回0。其比較規則是:拿出字符串的第一個字符與參數的第一個字符進行比較,如果兩者不等,比較結束,返回兩者的ascii差。這里有一點需要注意:如果兩個字符串的長度不同,並且一個字符串與另一個字符串的前面N個字符相等,那么這個方法返回返回兩個字符串長度之差。
  • public int compareToIgnore(String anotherString)
    與compareTo方法相似,但忽略大小寫。
  • public boolean equals(Object anotherObject)
    比較當前字符串和參數字符串,在兩個字符串相等的時候返回true,否則返回false。
  • public boolean equalsIgnoreCase(String anotherString)
    與equals方法相似,但忽略大小寫。
    例:
String s1 = "abcd"; String s2 = "abce"; String s3 = "ABC"; String s4 = "abcdefg"; String s5 = "abc"; System.out.println(s1.compareTo(s2)); System.out.println(s1.compareTo(s3)); System.out.println(s4.compareTo(s1)); System.out.println(s4.compareTo(s2)); System.out.println(s3.compareToIgnoreCase(s5)); System.out.println(s3.equals(s5)); System.out.println(s3.equalsIgnoreCase(s5)); 

輸出為:

-1
32
3
-1
0
false true 

5、字符串連接

  • public String concat(String str)
    將參數中的字符串str連接到當前字符串的后面,效果等價於"+"。

6、字符串中單個字符查找

  • public int indexOf(int ch/String str)
    用於查找當前字符串中字符或子串,返回字符或子串在當前字符串中從左邊起首次出現的位置,若沒有出現則返回-1。
  • public int indexOf(int ch/String str, int fromIndex)
    改方法與第一種類似,區別在於該方法從fromIndex位置向后查找。
  • public int lastIndexOf(int ch/String str)
    該方法與第一種類似,區別在於該方法從字符串的末尾位置向前查找。
  • public int lastIndexOf(int ch/String str, int fromIndex)
    該方法與第二種方法類似,區別於該方法從fromIndex位置向前查找。
    例:
String str = "I am a good student"; System.out.println(str.indexOf('a')); System.out.println(str.indexOf("good")); System.out.println(str.indexOf("w", 2)); System.out.println(str.lastIndexOf("a")); System.out.println(str.lastIndexOf("a", 3)); 

輸出為:

2
7
-1
5
2

7、字符串中字符的大小寫轉換

  • public String toLowerCase()
    返回將當前字符串中所有字符轉換成小寫后的新串
  • public String toUpperCase()
    返回將當前字符串中所有字符轉換成大寫后的新串

8、字符串中字符的替換

  • public String replace(char oldChar, char newChar)
    用字符newChar替換當前字符串中所有的oldChar字符,並返回一個新的字符串。
  • public String replaceFirst(String regex, String replacement)
    該方法用字符replacement的內容替換當前字符串中遇到的第一個和字符串regex相匹配的子串,應將新的字符串返回。
  • public String replaceAll(String regex, String replacement)
    該方法用字符replacement的內容替換當前字符串中遇到的所有和字符串regex相匹配的子串,應將新的字符串返回。
    例:
String str4 = "asdzxcasd"; System.out.println(str4.replace('a', 'g')); System.out.println(str4.replace("asd", "fgh")); System.out.println(str4.replaceFirst("asd", "fgh")); System.out.println(str4.replaceAll("asd", "fgh")); 

輸出為:

gsdzxcgsd
fghzxcfgh
fghzxcasd
fghzxcfgh

注意:replace和preplaceAll的區別

  1. replace的參數是char和CharSequence,即可以支持字符的替換,也支持字符串的替換(CharSequence即字符串序列的意思,說白了也就是字符串);
  2. replaceAll的參數是regex,即基於規則表達式的替換,比如,可以通過replaceAll("\d", "*")把一個字符串所有的數字字符都換成星號;
    例:
String src = new String("ab43a2c43d"); System.out.println(src.replace("3", "f")); System.out.println(src.replace('3', 'f')); System.out.println(src.replaceAll("\\d", "f")); System.out.println(src.replaceAll("a", "f")); System.out.println(src.replaceFirst("\\d", "f")); System.out.println(src.replaceFirst("4", "h")); 

輸出為:

ab4fa2c4fd
ab4fa2c4fd
abffafcffd
fb43f2c43d
abf3a2c43d
abh3a2c43d

9、其他方法

  • String trim()
    截去字符串兩端的空格,但對於中間的空格不處理。
String str = " a sd "; String str1 = str.trim(); int a = str.length();//a = 6 int b = str1.length();//b = 4 
  • boolean statWith(String prefix)或boolean endWith(String suffix)
    用來比較當前字符串的起始字符或子字符串prefix和終止字符或子字符串suffix是否和當前字符串相同,重載方法中同時還可以指定比較的開始位置offset。
String str = "asdfgh"; boolean a = str.statWith("as");//a = true boolean b = str.endWith("gh");//b = true 
  • contains(String str)
    判斷參數s是否被包含在字符串中,並返回一個布爾類型的值。
String str = "student"; str.contains("stu");//true str.contains("ok");//false 
  • String[] split(String str)
    將str作為分隔符進行字符串分解,分解后的字字符串在字符串數組中返回。
String str = "asd!qwe!zxc"; String[] str1 = str.split("!");//str1[0] = "asd";str1[1] = "qwe";str1[2] = "zxc"; 

字符串與基本類型的轉換

  1. 字符串轉換為基本類型
    java.lang包中有Byte、Short、Integer、Float、Double類的調用方法:
    1)public static byte parseByte(String s)
    2)public static short parseShort(String s)
    3)public static short parseInt(String s)
    4)public static long parseLong(String s)
    5)public static float parseFloat(String s)
    6)public static double parseDouble(String s)
    例如:
int n = Integer.parseInt("12"); float f = Float.parseFloat("12.34"); double d = Double.parseDouble("1.124"); 
  1. 基本類型轉換為字符串類型
    String類中提供了String valueOf()放法,用作基本類型轉換為字符串類型。
    1)static String valueOf(char data[])
    2)static String valueOf(char data[], int offset, int count)
    3)static String valueOf(boolean b)
    4)static String valueOf(char c)
    5)static String valueOf(int i)
    6)static String valueOf(long l)
    7)static String valueOf(float f)
    8)static String valueOf(double d)
    例如:
String s1 = String.valueOf(12); String s1 = String.valueOf(12.34); 
String常量池

常量池(constant pool)指的是在編譯期被確定,並被保存在已編譯的.class文件中的一些數據。它包括了關於類、方法、接口等中的常量,也包括字符串常量。Java為了提高性能,靜態字符串(字面量/常量/常量連接的結果)在常量池中創建,並盡量使用同一個對象,重用靜態字符串。對於重復出現的字符串直接量,JVM會首先在常量池中查找,如果常量池中存在即返回該對象。
例如:

public class test1 { public static void main(String[] args){ String str1 = "Hello";//生成了1個對象"Hello" //不會創建新的String對象,而是使用常量池中已有的"Hello", String str2 = "Hello"; System.out.println(str1 == str2); //true //使用new關鍵字會創建新的String對象,不管常量池里面有沒有相同的值 String str3 = new String("Hello");//生成了2個對象"Hello"和new String("Hello") System.out.println(str1 == str3); //false } } 
String對象不可變

String是常量,其對象一旦構造就不能再被改變。換句話說,String對象是不可變的,每一個看起來會修改String值的方法,實際上都是創造了一個全新的String對象,以包含修改后的字符串內容。而最初的String對象則絲毫未動。
例如:

public class StringTest02 { public static void main(String[] args) { String s = "hello"; String newS = StringTest02.append(s); System.out.println("String append--->" + s.toString()); StringBuilder sb = new StringBuilder("hello"); StringBuilder newSb = StringTest02.append(sb); System.out.println("StringBuilder append--->" +sb.toString()); } public static String append(String s) { s += "kitty"; return s; } public static StringBuilder append(StringBuilder sb) { return sb.append("kitty"); } } 

輸出為:

String append--->hello
StringBuilder append--->hellokitty

由上面的例子可見StringBuilder sb的值被改變了,而String s的值沒有變,所以String不可變的安全性就體現出來了

StringBuffer和StringBuilder支持的方法

StringBuffe和StringBuilder類的方法和String類部分類似,特有的方法有:

  • public StringBuffer append(String s)
    將指定的字符串追加到此字符序列。
  • public StringBuffer reverse()
    將此字符序列用其反轉形式取代。
  • public delete(int start, int end)
    移除此序列的子字符串中的字符。
  • public insert(int offset, int i)
    將 int 參數的字符串表示形式插入此序列中。
  • replace(int start, int end, String str)
    使用給定 String 中的字符替換此序列的子字符串中的字符。
  • int capacity()
    返回當前容量
  • void setCharAt(int index, char ch)
    將給定索引處的字符設置為 ch。
  • void setLength(int newLength)
    設置字符序列的長度。

String、StringBuffer和StringBuilder的區別

1. 對象的可變與不可變
String對象不可變,StringBuffer和StringBuilder對象可變。

2. 線程是否安全

  • String中的對象是不可變的,也就可以理解為常量,所以線程安全。
  • StringBuffer中的方法大都采用了synchronized關鍵字修飾,所以是線程安全的。
  • StringBuilder沒有對方法進行加同步鎖,所以是非線程安全的。

3. 字符串追加速度比較
StringBuilder > StringBuffer > String

4. StringBuffer和StringBuilder的共同點

  • StringBuffer和StringBuilder有公共的抽象父類AbstractStringBuilder
  • 抽象類與一個接口的區別是:抽象類中可以定義一些子類的公共方法,子類只需要增加新的功能,不需要重復寫已經存在的方法;而接口中只是對方法的申明和常量的定義。
  • StringBuilder和StringBuffer的方法都會調用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer會在方法上加上synchronized關鍵字,進行同步。
    如果程序不是多線程的,那么使用StringBuilder效率高於StringBuffer。

總結一下:
String:適用於少量的字符串操作的情況
StringBuilder:適用於單線程下在字符緩沖區進行大量操作的情況
StringBuffer:適用於多線程下在字符緩沖區進行大量操作的情況


作者:牽妳佐手
鏈接:https://www.jianshu.com/p/5d5ea61256b6


免責聲明!

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



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