Java中字串理解:
當我們使用String s = “hello”;語句建立字串的時候,首先會去常量池中查詢,如果有,就返回這個常量的地址,如果沒有,在常量池中建立並返回。world也是這樣的。比如這裡的“hello”,一開始是沒有的,所以要先建立,然後返回一個地址,比如0x01下一次,如果String s= “hello”;的時候,s指向的也會是這個0x01的地址。
String s = "hello"; //常量池中沒有常量"hello"就建立,假設地址值為0x001 String s1 = "hello"; //在常量池中查詢到"hello",因此s1也指向地址0x001 System.out.println(s==s1); //地址值相同,所以返回的結果為true System.out.println(s1.equals(s));//值相同,所以返回的結果為true
s += "world"//hello world
s+="world" =>"hello world" 在常量池建立一個0x03
之前的變數s會重新指向這個新的地址0x03,而不是原先的0x01 所以說字串一旦被建立,值就不可改變 這裡的值指的字串本身的值,而不是地址值
String s2 = new String("hello");//存放在堆中 System.out.println(s2.equals(s));//比較值是否相同,返回為true System.out.println(s2==s);//比較兩個物件地址值,返回false
new String()會在堆記憶體中建立物件,而引用變數String s1則會在棧裡面被建立,然後s1指向堆記憶體中被建立的String物件
”hello“也會在常量池中被建立,然後new String()建立的String物件會指向”hello“的地址,比如0x001,而String物件本身在堆記憶體中的地址,假設為0x0001,兩個地址是不一樣的
因此,這裡的引用變數s1指向的是堆記憶體中String物件地址0x0001,而不是直接指向常量池中”hello“的地址0x001
2.字串常量相加與變數相加的區別
- 字串如果是變數相加,是先開闢空間,然後再拼接
- 字串如果是常量相加,是先加,然後再去常量池裡找,如果找到了就返回,如果找不到就建立
String s1 = "hello"; String s2 = "world"; String s3 = "helloworld"; System.out.println(s3==(s1+s2)); //false System.out.println(s3==("hello"+"world")); //true
s3==(s1+s2)的結果是false,是因為變數相加是先在常量池中開闢空間,然後將拼接後的字串放入開闢的空間之中,因此地址會改變。
s3==(“hello”+“world”)的結果是true,是因為常量相加,是先拼接,然後在常量池中查詢,是否有拼接後的字串,如果有就返回這個地址值,如果沒有才會建立新的空間。因為之前s3已經建立了”helloworld“字串,所以返回的是s3指向的這個地址。因此地址相同。
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = s1+s2;
String s5 = "helloworld";
System.out.println(System.identityHashCode(s3)); //第一行
System.out.println(System.identityHashCode(s4)); //第二行
System.out.println(System.identityHashCode(s5)); //第三行
第一行與第三行返回的值相同,說明s5優先指向的地址是s3一開始就建立的地址
3.建立字串的四種方法
//建立字串物件的四種方法
//public String():建立一個空白字串物件,不含有任何內容 String s1 = new String(); System.out.println("s1:" + s1); //public String(char[] chs):根據字元陣列的內容,來建立字串物件 char[] chs = {'a', 'b', 'c'}; String s2 = new String(chs); System.out.println("s2:" + s2); //public String(byte[] bys):根據位元組陣列的內容,來建立字串物件 byte[] bys = {97, 98, 99}; String s3 = new String(bys); System.out.println("s3:" + s3); //String s = “abc”; 直接賦值的方式建立字串物件,內容就是abc String s4 = "abc"; System.out.println("s4:" + s4);
//顯示結果
a1:abc
s2:abc
s3:abc
s4:abc
4.字串常用的方法
字串的方法 解釋說明
charAt(): 會根據索引獲取對應的字元 s.charAt(i) i表示索引 length(): 會返回字串的長度 s.length()
substring(start,end) 擷取字串 s.substrng(0,3) a b c
substring(start) s.substrng(1) bcde
replace(需要替換的文字,替換成的東西)
5.StringBuilder與StringBuffer、StringJoin
StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("a").append("b").append("c"); System.out.println(stringBuilder.toString()); stringBuilder.reverse(); System.out.println(stringBuilder.toString()); abc cba
//1.建立物件 StringJoiner sj = new StringJoiner(", ","[","]"); //2.新增元素 sj.add("aaa").add("bbb").add("ccc"); int len = sj.length(); System.out.println(len);//15 //3.列印 System.out.println(sj);//[aaa, bbb, ccc] String str = sj.toString(); System.out.println(str);//[aaa, bbb, ccc]
在 Java 語言中,由於 String 類是final 型別的,所以使用 String 定義的字串是一個常量,因此它一旦建立,其內容和長度是不可改變的。如果需要對一個字串進行修改,則只能建立新的字串。
解決方法:可以使用 StringBuffer 類(也稱字串緩衝區)來操作字串。
說明:StringBuffer 類和 String 類最大的區別在於它的內容和長度都是可以改變的。StringBuffer 類似一個字元容器,當在其中新增或刪除字元時,所操作的都是這個字元容器,因此並不會產生新的 StringBuffer 物件。
1.使用StringBuffer類的構造方法初始化字串物件 StringBuffer 變數名=new String(字串); 2.藉助String類來建立StringBuffer類物件 String s="abc"; StringBuffer s5=new StringBuffer(s); 如果直接 StringBuffer sb = "abc";會報錯
StringBuffer s1=new StringBuffer("abcd1234!?,;"); StringBuffer s2=new StringBuffer("987654321987654"); StringBuffer s3=new StringBuffer("987654321"); System.out.println("↓↓↓StringBuffer類的一些常用方法如下↓↓↓"); System.out.println("-----------------------------------------------------"); System.out.println("字串s1的長度為:" + s1.length());//返回字串的實際長度 System.out.println("-----------------------------------------------------"); System.out.println("字串s1所佔容器的大小為:" + s1.capacity());//返回字串所佔容器的總大小 System.out.println("-----------------------------------------------------"); System.out.println("獲取字串s1中第2個位置的字元:" + s1.charAt(2)); System.out.println("-----------------------------------------------------"); System.out.println("子字串'654'第一次出現在字串s2中的索引為:" + s2.indexOf("654")); System.out.println("從指定的索引6開始搜尋,返回子字串'654'第一次出現在字串s2中的索引:" + s2.indexOf("654",6)); System.out.println("-----------------------------------------------------"); System.out.println("子字串'987'最後一次出現在字串s2中的索引為:" + s2.lastIndexOf("987")); System.out.println("從指定的索引5開始反向搜尋,返回字串'87'在字串s2中最後一次出現的索引:" + s2.lastIndexOf("87",5)); System.out.println("-----------------------------------------------------"); s1.append('x');//在字串s1的末尾新增字元'c' s1.append("Java");//在字串s1的末尾新增字串"Java" System.out.println("修改後的字串s1為:" + s1); System.out.println("-----------------------------------------------------"); s1.insert(4,"abcd");//在第4個位置插入字串"abcd" System.out.println("修改後的字串s1為:" + s1); System.out.println("-----------------------------------------------------"); s1.deleteCharAt(1);//刪除字串s1中第一個位置的字元 s1.delete(2,5);//刪除字串s1中第2到第4個位置的字元 System.out.println("修改後的字串s1為:" + s1); System.out.println("-----------------------------------------------------"); s1.replace(4,8,"5678");//將字串s1中第4到第7個位置的字串修改為"5678" System.out.println("修改後的字串s1為:" + s1); System.out.println("-----------------------------------------------------"); s1.setCharAt(1,'b');//將字串s1中第一個位置的字元修改為'b' System.out.println("修改後的字串s1為:" + s1); System.out.println("-----------------------------------------------------"); s2.reverse();//將字串s2反轉 System.out.println("修改後的字串s2為:" + s2); System.out.println("-----------------------------------------------------"); System.out.println("擷取字串s1從第4個位置開始到結尾:" + s1.substring(4)); System.out.println("-----------------------------------------------------"); System.out.println("擷取字串s1從第4個位置開始到第7個位置結尾:" + s1.substring(4,8)); System.out.println("-----------------------------------------------------"); System.out.println("獲取s1的變數型別:" + s1.getClass().getName()); System.out.println("將物件資訊轉化為字串:" + s2.toString());
↓↓↓StringBuffer類的一些常用方法如下↓↓↓ ----------------------------------------------------- 字串s1的長度為:12 ----------------------------------------------------- 字串s1所佔容器的大小為:28 ----------------------------------------------------- 獲取字串s1中第2個位置的字元:c ----------------------------------------------------- 子字串'654'第一次出現在字串s2中的索引為:3 從指定的索引6開始搜尋,返回子字串'654'第一次出現在字串s2中的索引:12 ----------------------------------------------------- 子字串'987'最後一次出現在字串s2中的索引為:9 從指定的索引5開始反向搜尋,返回字串'87'在字串s2中最後一次出現的索引:1 ----------------------------------------------------- 修改後的字串s1為:abcd1234!?,;xJava ----------------------------------------------------- 修改後的字串s1為:abcdabcd1234!?,;xJava ----------------------------------------------------- 修改後的字串s1為:accd1234!?,;xJava ----------------------------------------------------- 修改後的字串s1為:accd5678!?,;xJava ----------------------------------------------------- 修改後的字串s1為:abcd5678!?,;xJava ----------------------------------------------------- 修改後的字串s2為:456789123456789 ----------------------------------------------------- 擷取字串s1從第4個位置開始到結尾:5678!?,;xJava ----------------------------------------------------- 擷取字串s1從第4個位置開始到第7個位置結尾:5678 ----------------------------------------------------- 獲取s1的變數型別:java.lang.StringBuffer 將物件資訊轉化為字串:456789123456789