java.lang.String 是字串
它的底層是一個字元陣列,所以它的很多特性就是陣列的特性
1 字串一旦被建立,這個字串物件就不可以更改了
2 爲了提升字串的存取效率,java虛擬機器採用了一種快取的技術,String是一個參照數據型別,那麼String的值應該儲存在堆記憶體吧?
但是字串不一樣,字串物件都會在靜態區有一個字串常數池
3 在程式執行中,如果程式要用到某一個字串,比如(「abc」),虛擬機器首先會去字串常數池中搜尋,有沒有這個字串,
如果已經有了,就直接指向這個字串,不需要再建立一個
如果沒有,就建立一個,然後再指向
public class String_01 {
public static void main(String[] args) {
//建立一個abc字串物件,直接儲存再常數池中,然後將記憶體地址賦值給變數s1
//儘管沒有new但是s1還是指向字串物件
String s1 = "abc";
//s1是main方法中區域性變數,並且沒有使用final修飾,所以可以更改s1的值
//因爲s1只儲存了一個記憶體地址,所以s1可以重新賦值一個新的記憶體地址
//但是abc物件,更改不了
s1 = "def";
String s2 = "Hello";
String s3 = "Hello";
String s4 = "hello";
System.out.println(s2 == s3);
System.out.println(s2.toString());
System.out.println(s2.equals(s3));
//建立兩個物件,一個Hello 一個hello
//true比較值,因爲String覆寫了
System.out.println(s2.equals(s3));
String s5 = new String("abc");
String s6 = new String("abc");
//false,因爲這種方法,s5和s6分別指向堆記憶體,堆記憶體再指向數據
System.out.println(s5 == s6);
System.out.println(s5.equals(s6));
}
}
注意
使用String的時候,要注意,儘量不要做頻繁的拼接操作
因爲字串一旦建立,不能更改,如果拼接,會頻繁的建立字串物件,浪費空間
public class String_02 {
public static void main(String[] args) {
String[] arr = {"a","b","c"};
String tmp = "";
for(int i = 0;i < arr.length;i++) {
tmp += arr[i];
}
//a,b,c,ab,abc
System.out.println(tmp);
}
}
public class String_03 {
public static void main(String[] args) {
//1
String s1 = "abc";
//2
String s2 = new String("abc");
//3 傳遞位元組陣列,轉換爲字串
byte[] bytes = {97,98,99};
String s3 = new String(bytes);
System.out.println(s3);
//4 擷取位元組陣列中的一部分
//下標從1開始(包含), 取兩個
String s4 = new String(bytes,1,2);
System.out.println(s4);
//5 傳遞字串陣列,轉換爲字串
char[] chars = {'q','w','e','r'};
String s5 = new String(chars);
System.out.println(s5);
//6 擷取字元陣列的一部分
String s6 = new String(chars,0,2);
System.out.println(s6);
}
}
public class String_04 {
public static void main(String[] args) {
// 1 char charAt(int index):獲取字串中,某個位置上的字元,相當於arr[index]
String s1 = "qwer";
char c1 = s1.charAt(2);
System.out.print(c1);
//2 boolean endsWith(String suffix):判斷字串是否以指定字串結尾
//startsWith(String prefix)判斷開始
//true
System.out.println("Hello.java".endsWith(".java"));
//false 注意 空格
System.out.println("Hello.java".endsWith(".java "));
//3 boolean equalsIgnoreCase(String anotherString):不區分大小寫比較兩個字串是否相等
System.out.println("abc".equals("ABC"));
System.out.println("abc".equalsIgnoreCase("ABC"));
//4 byte[] getBytes();:把字串轉換爲位元組陣列
byte[] bytes = "abc".getBytes();
for(byte b : bytes) {
System.out.println(b);
}
System.out.println("-----");
//5 int indexOf(String str): 獲取指定字串的起始索引,找不到就返回-1
System.out.println("cniuhaushd213hxhdd2".indexOf("d2"));//9
//6 int indexOf(String str,int fromIndex): 從指定位置開始查詢,找不到返回-1
System.out.println("cnuasdjkdncu22123nnnadios".indexOf("c",1));
//7 int lastIndexOf(String str):最後一次出現位置的索引,找不到返回-1
System.out.println("dasdasdadaojf12eoijo".lastIndexOf("c"));
//8 int length(): 獲取字串長度
System.out.println("abc".length());
//9 String replaceAll(String regex,String replacement):把指定字元換爲指定字元
//還有一個方法replace這兩個功能一樣,只不過replaceAll支援正則表達式
System.out.println("12h,dha!sioh@#21從!23<>".replaceAll("[^0-9a-zA-Z]", "" ));
//10 Strubg[] split(String regix):分割字串,需要指定分隔符,返回值是字串陣列,支援正則表達式
String myTime = "2008,08,08";
//如果是以.點分割,需要\\.因爲split支援正則表達式,在正則表達式中有特殊含有,所以需要跳脫
//在正則表達式中,通過\.對.進行跳脫,但是\在java中也是轉移服,所以需要\\.來跳脫\
String[] ymd = myTime.split(",");
for(String string : ymd) {
System.out.println(string);
}
System.out.println("----");
//11 String substring(int begin):獲取該字串以某個下標開始的字串(包含)
System.out.println("abcdefg".substring(2));//cedfg
//12 String substring(int beginIndex,int endIdex);"
//以某個下標開始(包含),到某個下標結束的子字串(不包含)
System.out.println("abcdefg".substring(2,6));//cdef
//13 char[] toCharArray():轉換爲char陣列
char[] c2 = "qwer".toCharArray();
for(char c : c2) {
System.out.println(c);
}
System.out.println("----");
//14 轉大寫和小寫
System.out.println("asdUId".toUpperCase());
System.out.println("asdUId".toLowerCase());
//15 String trim():去除字串首尾的空格
System.out.println(" 1 dcz s ".trim());
//16 static String valueOf(Object obj): 呼叫物件的toString方法,並處理null值
}
}
public class String_06 {
public static void main(String[] args) {
// String是不能任意拼接的字串
String s1 = "ab";
String a = "a";
String b = "b";
//兩個字面量相加,在編譯階段,會把+去掉,這個 + 相當於字串連線符
String s3 = "a" + "b";
//這種不一樣,因爲在編譯,沒有辦法確定a和b的值的,所以只能等執行起來之後在操作
//會建立一個StringBuffer物件進行拼接,然後再通過toString方法把拼接之後的值返回
//因爲toString方法中,是new String(xxx);的形式返回,所以會指向堆記憶體
//所以使用 == 比較就不對,equals()比較 就沒有問題
//所以 不管哪種賦值方式,我們比較字串就使用equals()是最正確的,也是最保準的
String s2 = a + b;
String s4 = "a" + new String("b");
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
System.out.println(s1 ==s4);//false
System.out.println(s1.equals(s4));
}
}