目錄
1.String概述
1.1 字符串的不變性
1.2?創建String對象兩種方式的區別
?1.3 字符串中的構造方法?
1.4 字符串判斷功能的方法
1.5 字符串獲取功能的方法?
1.6 字符串轉換功能的方法
1.7 字符串替換功能的方法?
2.StringBuffer
2.1 構造方法
2.2 插入方法
2.2.1 append()方法
2.2.2 Insert()方法
2.3 刪除方法
2.3.1 deleteCharAt()方法
2.3.2 delete()方法
2.4 其他方法
2.4.1 replace()方法
?2.4.2 reverse()方法
2.4.3 substring()方法?
3.StringBuilder
4.String,StringBuffer,StringBuilder對比
1.String概述
java中所有用" "雙引號括起來的都是String類的對象,String類的對象有以下特征
1.1 字符串的不變性
字符串對象一旦創建就不能改變
public class String2 {public static void main(String[] args) {//字符串不變,它們的值在創建后不能被更改String s = "abcd";//abcd 第一個字符串對象s += "efg";//abcdefg 第二個字符串對象s += "aaaa";//abcdefgaaaa 第三個字符串對象System.out.println(s);}
}
上述代碼,看似是s一直+=字符串,s好像是變了,但其實這是三個不同的字符串對象,只是s的指向一直在改變,所以當+=字符串次數很多時,是相當占用資源的
1.2?創建String對象兩種方式的區別
方式一:
public class String1 {/*java.lang.Stringjava中所有字符串都是此類的實例"abc" -->字符串對象 底層是一個char數組 private final char value['a','b','c'];字符串對象創建方式:1.String s = "abc"創建時會先去字符串常量池中查找有沒有值相同的對象,如果沒有,就創建一個字符串對象,并返回地址如果字符串常量池中有,不用創建新的,直接返回已存在的對象的地址
*/public static void main(String[] args) {String s = "abc";String ss = "abc";System.out.println(s == ss);//trueSystem.out.println(s.equals(ss));//true}}
直接用一個字符串常量賦值給String類的對象,eg:String s ="abc";
用這種方式創建一個字符串對象,編譯器會先在字符串常量池中找有沒有與其值相同的字符串,如果有,則直接將該引用指向字符串常量池中的字符串,如果沒有會在字符串常量池中創建一個該字符串,并將引用指向該對象,所以用這種方式創建兩個值相同的字符串時用 == 判斷返回的是true,因為它們指向字符串常量池中的同一個字符串
方式二:
public class String1 {/*2.String s1 = new String("abc");new 每次都是在堆中創建新的字符串對象*/public static void main(String[] args) {String s = "abc";String ss = "abc";System.out.println(s == ss);//trueSystem.out.println(s.equals(ss));//trueString s1 = new String("abc");String s2 = new String("abc");System.out.println(s1 == s2);//falseSystem.out.println(s1.equals(s2));//true}}
?用new調用構造方法創建對象,這種方式在創建時地址肯定是不一樣的,new創建對象就是在堆中開辟不同的空間,然后將字符串填充進去,用==判斷兩個值相同的字符串對象時返回的是false
?1.3 字符串中的構造方法?
(1)String()
無參構造
String s1 = new String();
(2)String(String s)
用一個字符串構造字符串對象
String s2 = new String("abc");
(3)String(byte[ ] bytes)
用一個字節數組構造字符串對象
String s3 = "你好";byte[] bytes = s3.getBytes();//編碼 把字符轉為 字節數組(數字)System.out.println(Arrays.toString(bytes));String s4 = new String(bytes,"GBK");//解碼 把字節數組轉為字符System.out.println(s4);
字符串中有一個getBytes()方法,可以將字符串轉為字節數組,然后再利用String(byte[ ] bytes)將字節數組轉為字符串可實現編碼和解碼
(4)String(char[ ] chars)
用一個字符數組構造字符串對象
String s5 = "cab";char[] chars = s5.toCharArray();//把字符串轉為字符數組Arrays.sort(chars);String s6 = new String(chars);//把字符數組轉為字符串System.out.println(s6);
字符串中有一個toCharArray()方法可以將字符串轉為字符數組,可以配合String(char[ ] chars)使用
1.4 字符串判斷功能的方法
public class String4 {/*判斷功能boolean equals(Object obj) //比較兩個字符串的內容是否相等boolean equalsIgnoreCase(String str)//判斷兩個字符串的內容是否相等,忽略大小寫boolean contains(String str)//判斷字符串中是否包含指定的子串boolean isEmpty()//判斷字符串是否為空串""boolean startsWith(String prefix)//判斷是否以指定的字符串開頭boolean endsWith(String suffix)//判斷是否以指定的字符串結尾*/public static void main(String[] args) {String s1 = new String("abcd");String s2 = new String("abcD");System.out.println(s1.equals(s2));System.out.println(s1.equalsIgnoreCase(s2));System.out.println(s1.contains("ac"));System.out.println(s1.isEmpty());System.out.println(s1.startsWith("ab"));System.out.println(s1.endsWith("cd"));}
}
判斷功能?
? ? (1) boolean equals(Object obj) //比較兩個字符串的內容是否相等
? ? (2)?boolean equalsIgnoreCase(String str)//判斷兩個字符串的內容是否相等,忽略大小寫
? ? (3) boolean contains(String str)//判斷字符串中是否包含指定的子串
? ? (4) boolean isEmpty()//判斷字符串是否為空串""
? ? (5) boolean startsWith(String prefix)//判斷是否以指定的字符串開頭
? ? (6) boolean endsWith(String suffix)//判斷是否以指定的字符串結尾
1.5 字符串獲取功能的方法?
public class String5 {/*獲取功能int length();//獲取字符串長度char charAt(int index);//獲取指定位置上的字符int indexOf(String str);返回指定字符串首次出現的位置int indexOf(String str,int fromIndex);從指定的位置位置開始查找,返回指定字符串首次出現的位置int lastIndex(String str);//從右向左查找,返回指定字符串首次出現的位置String substring(int start);//從指定的開始位置開始截取一個字符串副本到完String substring(int start,int end)從指定的開始位置截取一個字符串副本到指定位置(不包含結束位置)*/public static void main(String[] args) {String s1 = "abcdefgcd";//012345678System.out.println(s1.length());System.out.println(s1.charAt(4));for (int i = 0; i < s1.length(); i++) {System.out.print(s1.charAt(i));}System.out.println();System.out.println(s1.indexOf("cd"));System.out.println(s1.indexOf("c",3));System.out.println(s1.lastIndexOf("c"));System.out.println(s1.lastIndexOf("c",6));String s2 = s1.substring(3);String s3 = s1.substring(0,6);//左閉右開System.out.println(s2);System.out.println(s3);}
}
獲取功能
? ?(1)? int length();//獲取字符串長度
? ?(2)? char charAt(int index);//獲取指定位置上的字符
? ?(3)? int indexOf(String str);返回指定字符串首次出現的位置
? ?(4)? int indexOf(String str,int fromIndex);從指定的位置位置開始查找,返回指定字符串首次出現的位置
? ?(5)? int lastIndex(String str);//從右向左查找,返回指定字符串首次出現的位置
? ?(6)? String substring(int start);//從指定的開始位置開始截取一個字符串副本到完
? ?(7)? String substring(int start,int end)從指定的開始位置截取一個字符串副本到指定位置(不包含結束位置)
1.6 字符串轉換功能的方法
public class String6 {public static void main(String[] args) {/*轉換功能byte[] getBytes();將字符串轉為字節數組char[] toCharArray()將字符串轉為字符數組static String valueOf(char[] chs)將字符數組轉為字符串static String valueOf(int a)將傳入的參數轉為字符串類型String toLowerCase()將英文字母轉為小寫String toUpperCase()將英文字母轉為大寫String concat(String str)拼接指定的字符串內容到原字符串末尾,返回一個新的字符串對象Stirng[] split(分割符);將一個字符串用指定的分隔符拆分成一個字符串數組*/String s = String.valueOf(1234);System.out.println(s.charAt(1));int a = Integer.parseInt(s);String s1 = String.valueOf("abc".toCharArray());System.out.println(s1);String s2 = "account=admin;account=123;account=456";System.out.println(s2.toLowerCase());System.out.println(s2.toUpperCase());String s3 = s2.concat("aaa");System.out.println(s3);String[] strings = s2.split(";");System.out.println(Arrays.toString(strings));}
}
? ? ? ? 轉換功能
? ? ? ? ? ?(1) byte[] getBytes();將字符串轉為字節數組
? ? ? ? ? ?(2) char[] toCharArray()將字符串轉為字符數組
? ? ? ? ? ?(3) static String valueOf(char[] chs)將字符數組轉為字符串
? ? ? ? ? ?(4) static String valueOf(int a)將傳入的參數轉為字符串類型
? ? ? ? ? ?(5) String toLowerCase()將英文字母轉為小寫
? ? ? ? ? ?(6) String toUpperCase()將英文字母轉為大寫
? ? ? ? ? ?(7) String concat(String str)拼接指定的字符串內容到原字符串末尾,返回一個新的字符串對象
? ? ? ? ? ?(8) Stirng[] split(分割符);將一個字符串用指定的分隔符拆分成一個字符串數組
1.7 字符串替換功能的方法?
public class String7 {/*替換功能String replace(char old,char new)用新的字符替換字符串中指定的字符String replace(String old,String new)用新的字符串替換字符串中指定的字符串replaceAll(String regex, String replacement)用新內容替換字符串中正則表達式匹配的字符串replaceFirst(String regex, String replacement)用新內容替換字符串中正則表達式匹配的字符串,只替換第一個String trim()去除字符串兩端的空格*/public static void main(String[] args) {String s = " 2b3 cd 2efc5g ";System.out.println(s.replace("2","C"));System.out.println(s.replaceAll("\\d","C"));System.out.println(s.replaceFirst("\\d","C"));System.out.println(s.length());System.out.println(s.trim().length());}}
替換功能
? ? ? ?(1) String replace(char old,char new) 用新的字符替換字符串中指定的字符
? ? ? ?(2) String replace(String old,String new) 用新的字符串替換字符串中指定的字符串
? ? ? ?(3) replaceAll(String regex, String replacement) 用新內容替換字符串中正則表達式匹配的字符串
? ? ? ?(4) replaceFirst(String regex, String replacement) 用新內容替換字符串中正則表達式匹配的字符串,只替換第一個
? ? ? ?(5) String trim() 去除字符串兩端的空格?
注意:
這里要注意replace和replaceAll方法的區別,兩個都可以對所有字符進行替換,不要被名字迷惑,replaceAll()方法的匹配方式可以傳入一個正則表達式,而replace()方法傳入的是用誰替換誰是字符串
2.StringBuffer
因為String類的對象一旦創建就不能改變,并且在進行字符串的拼接時,要頻繁創建新的對象,既占用空間,又耗時,所以有了StringBuffer類,StringBuffer類的對象底層的數組沒有被final修飾,所以在操作時,可以直接在原來的字符串上改變,不用創建新的字符串對象
2.1 構造方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s1 = new StringBuffer();//空的構造方法指定底層數組長度是16StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16StringBuffer s3 = new StringBuffer(10);//還可以指定底層數組長度}
}
?(1) StringBuffer()
空的構造函數,底層會產生一個默認長度為16的char數組
(2) StringBuffer(String str)
用一個字符串初始化StringBuffer,底層會產生一個字符串長度+16的char數組
(3) StringBuffer(int capacity)
也可以用該構造方法指定底層數組的長度
2.2 插入方法
2.2.1 append()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s1 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s1.append("abcd");//向字符串末尾添加內容System.out.println(s1);s1.append("efg");System.out.println(s1);s1.append("hijk");System.out.println(s1);s1.append("aaaa");System.out.println(s1);}
該方法是直接在原字符串末尾進行追加,每追加一次就會判斷當前長度是否大于數組長度,如果大于就會new一個新的字符數組,長度是2 * length(元數組長度) + 2個,并將原來數組中的值拷貝到新數組中,在改變原來數組的引用
2.2.2 Insert()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s2.insert(1,"A");//向指定的位置上插入指定的字符串System.out.println(s2);}
}
Insert()方法就是在指定位置處插入一個字符或字符串
2.3 刪除方法
2.3.1 deleteCharAt()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s1.deleteCharAt(1);//刪除指定位置上的字符System.out.println(s2);
}
該方法是刪除指定位置處的字符
2.3.2 delete()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s2.delete(0,3);//刪除指定區間的元素,左閉右開System.out.println(s2);}
}
刪除指定區間的字符串,左閉右開
2.4 其他方法
2.4.1 replace()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s2.replace(0,4,"AAA");System.out.println(s2);}
}
該方法使用一個字符串替換指定區間內的字符串
?2.4.2 reverse()方法
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16s2.reverse();//反轉字符串System.out.println(s2);}
}
該方法可以反轉一個字符串
2.4.3 substring()方法?
public class StringBuffer1 {public static void main(String[] args) {StringBuffer s2 = new StringBuffer("abcd");//有參構造,底層數組長度為字符串長度+16String s2 = s1.substring(0,5);//截取字符串,從StringBuffer中截取一個字符串副本,返回給一個新的String對象,StringBuffer對象不變System.out.println(s2);}
}
該方法是截取指定區間(左閉右開)的字符串,原字符串不變,是拷貝了一份進行截取
3.StringBuilder
StringBuilder和StringBuffer基本相同,都是繼承了AbstractStringBuilder,相當于向外提供了兩個類,但實際上調用的是都是AbstractStringBuilder中的方法,唯一的區別就是StringBuffer的方法中加了synchronized關鍵字,是線程安全的,而StringBuilder是線程不安全的
4.String,StringBuffer,StringBuilder對比
String:是一個值不可以改變的字符串
StringBuffer:值可以改變且不需要創建新對象, ?方法上都加了鎖, 是在多線程(任務)執行時是線程安全的
StringBuilder: 值可以改變且不需要創建新對象, 由于方法上都沒有加鎖,在多線程(任務)執行時是線程不安全的, 適合單線程