String、StringBuffer、StringBuilder詳解

String類

字符串廣泛應(yīng)用在java編程中,String類在java.lang包中,String類是final修飾的,不能被繼承,String類對(duì)象創(chuàng)建后不能修改,由0或多個(gè)字符組成,包含在一對(duì)雙引號(hào)之間。今天來談?wù)凷tring類中一些常用的方法和一些需要注意的點(diǎn)。


構(gòu)造方法

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

String str1 = new String(); 

2、public String(String value)
用已知的字符串value創(chuàng)建一個(gè)String對(duì)象。

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

3、public String(char[] value)
用字符數(shù)組value創(chuàng)建一個(gè)String對(duì)象。

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

4、public String(char chars[], int startIndex, int numChars)
用字符數(shù)組chars的startIndex開始的numChars個(gè)字符創(chuàng)建一個(gè)String對(duì)象。

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

5、public String(byte[] values)
用比特?cái)?shù)組values創(chuàng)建一個(gè)String對(duì)象。

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

6、public String(byte[] values,int startIndex, int numChars)
用字符數(shù)組byte的startIndex開始的numChars個(gè)字符創(chuàng)建一個(gè)String對(duì)象。

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

String類常用方法

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

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

3、截取字符串

  • substring(int beginIndex)
    該方法從beginIndex位置起(包含這個(gè)位置)到最后截取一個(gè)字符串返回。
    [beginIndex,最后]
  • substring(int beginIndex,endIndex)
    該方法從beginIndex位置起(包含這個(gè)位置)到endIndex - 1截取一個(gè)字符串返回。
    [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)
    該方法是對(duì)字符串內(nèi)容按字典順序進(jìn)行大小比較,通過返回的整數(shù)值指明當(dāng)前字符串與參數(shù)字符串的大小關(guān)系。若當(dāng)前對(duì)象比參數(shù)大則返回正整數(shù),反之返回負(fù)整數(shù),相等返回0。其比較規(guī)則是:拿出字符串的第一個(gè)字符與參數(shù)的第一個(gè)字符進(jìn)行比較,如果兩者不等,比較結(jié)束,返回兩者的ascii差。這里有一點(diǎn)需要注意:如果兩個(gè)字符串的長(zhǎng)度不同,并且一個(gè)字符串與另一個(gè)字符串的前面N個(gè)字符相等,那么這個(gè)方法返回返回兩個(gè)字符串長(zhǎng)度之差。
  • public int compareToIgnore(String anotherString)
    與compareTo方法相似,但忽略大小寫。
  • public boolean equals(Object anotherObject)
    比較當(dāng)前字符串和參數(shù)字符串,在兩個(gè)字符串相等的時(shí)候返回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)
    將參數(shù)中的字符串str連接到當(dāng)前字符串的后面,效果等價(jià)于"+"。

6、字符串中單個(gè)字符查找

  • public int indexOf(int ch/String str)
    用于查找當(dāng)前字符串中字符或子串,返回字符或子串在當(dāng)前字符串中從左邊起首次出現(xiàn)的位置,若沒有出現(xiàn)則返回-1。
  • public int indexOf(int ch/String str, int fromIndex)
    改方法與第一種類似,區(qū)別在于該方法從fromIndex位置向后查找。
  • public int lastIndexOf(int ch/String str)
    該方法與第一種類似,區(qū)別在于該方法從字符串的末尾位置向前查找。
  • public int lastIndexOf(int ch/String str, int fromIndex)
    該方法與第二種方法類似,區(qū)別于該方法從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、字符串中字符的大小寫轉(zhuǎn)換

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

8、字符串中字符的替換

  • public String replace(char oldChar, char newChar)
    用字符newChar替換當(dāng)前字符串中所有的oldChar字符,并返回一個(gè)新的字符串。
  • public String replaceFirst(String regex, String replacement)
    該方法用字符replacement的內(nèi)容替換當(dāng)前字符串中遇到的第一個(gè)和字符串regex相匹配的子串,應(yīng)將新的字符串返回。
  • public String replaceAll(String regex, String replacement)
    該方法用字符replacement的內(nèi)容替換當(dāng)前字符串中遇到的所有和字符串regex相匹配的子串,應(yīng)將新的字符串返回。
    例:
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的區(qū)別

  1. replace的參數(shù)是char和CharSequence,即可以支持字符的替換,也支持字符串的替換(CharSequence即字符串序列的意思,說白了也就是字符串);
  2. replaceAll的參數(shù)是regex,即基于規(guī)則表達(dá)式的替換,比如,可以通過replaceAll("\d", "*")把一個(gè)字符串所有的數(shù)字字符都換成星號(hào);
    例:
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()
    截去字符串兩端的空格,但對(duì)于中間的空格不處理。
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)
    用來比較當(dāng)前字符串的起始字符或子字符串prefix和終止字符或子字符串suffix是否和當(dāng)前字符串相同,重載方法中同時(shí)還可以指定比較的開始位置offset。
String str = "asdfgh";
boolean a = str.statWith("as");//a = true
boolean b = str.endWith("gh");//b = true
  • contains(String str)
    判斷參數(shù)s是否被包含在字符串中,并返回一個(gè)布爾類型的值。
String str = "student";
str.contains("stu");//true
str.contains("ok");//false
  • String[] split(String str)
    將str作為分隔符進(jìn)行字符串分解,分解后的字字符串在字符串?dāng)?shù)組中返回。
String str = "asd!qwe!zxc";
String[] str1 = str.split("!");//str1[0] = "asd";str1[1] = "qwe";str1[2] = "zxc";

字符串與基本類型的轉(zhuǎn)換

  1. 字符串轉(zhuǎn)換為基本類型
    java.lang包中有Byte、Short、Integer、Float、Double類的調(diào)用方法:
    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. 基本類型轉(zhuǎn)換為字符串類型
    String類中提供了String valueOf()放法,用作基本類型轉(zhuǎn)換為字符串類型。
    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文件中的一些數(shù)據(jù)。它包括了關(guān)于類、方法、接口等中的常量,也包括字符串常量。Java為了提高性能,靜態(tài)字符串(字面量/常量/常量連接的結(jié)果)在常量池中創(chuàng)建,并盡量使用同一個(gè)對(duì)象,重用靜態(tài)字符串。對(duì)于重復(fù)出現(xiàn)的字符串直接量,JVM會(huì)首先在常量池中查找,如果常量池中存在即返回該對(duì)象。
例如:

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

String是常量,其對(duì)象一旦構(gòu)造就不能再被改變。換句話說,String對(duì)象是不可變的,每一個(gè)看起來會(huì)修改String值的方法,實(shí)際上都是創(chuàng)造了一個(gè)全新的String對(duì)象,以包含修改后的字符串內(nèi)容。而最初的String對(duì)象則絲毫未動(dòng)。
例如:

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不可變的安全性就體現(xiàn)出來了

StringBuffer和StringBuilder支持的方法

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

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

String、StringBuffer和StringBuilder的區(qū)別

1. 對(duì)象的可變與不可變
String對(duì)象不可變,StringBuffer和StringBuilder對(duì)象可變。

2. 線程是否安全

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

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

4. StringBuffer和StringBuilder的共同點(diǎn)

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

總結(jié)一下:
String:適用于少量的字符串操作的情況
StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
StringBuffer:適用于多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況

請(qǐng)尊重作者勞動(dòng)成果,轉(zhuǎn)載請(qǐng)標(biāo)明原文鏈接:http://www.itdecent.cn/p/5d5ea61256b6

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

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