String在Java里面JDK1.8后它屬於一個特殊的類,在創建一個String基本對象的時候,String會向“ 字符串常量池(String constant pool)” 進行檢索是否有該數據(字符串)存在,如果存在則向該數據進行實例引用,返回到創建的String對象。
所以當創建兩個不同名字,相同字符串的常量時,不可能會有兩個不同的存儲內存。
String常量,在JDK1.8后便可以任意修改,不會創建新的內存地址對內存應用的浪費。
(常量與常量比較)
String de="你好婷婷"; String de1=de; //這是String常量 de1="你好婷婷"; //修改de1,檢索修改的值,在常量池是否存在一樣的 System.out.println(de==de1);//結果true
結論:修改常量,修改的時候會在常量池檢索是否有相同的字符串存在。有則將這個地址返回給修改的String常量(de1)
String對象,不可以更改。雖然表面String的對象值改變了,但是修改的同時也在內存開辟了新的空間,以前的就空間還存在:造成對堆內存的浪費。
1.(常量與對象比較)
String dee=new String("你好婷婷");
//這是String對象
String de=dee;
//這是String常量
System.out.println(de==dee);
結論: String常量可以指向對象的內存,上面代碼已經·有dee對象,當de常量指向dee時,會直接返回內存地址到de,不會開辟新空間。
String de="你好婷婷";
//這是String常量
String dee=new String(de);
//這是String對象
System.out.println(de==dee);//結果為false
結論: String對象不能指向String常量,當創建dee對象的時候,就算不賦值也會在堆里面開辟一個為null的空間。
2.(對象與對象比較)
String dee=new String("你好婷婷");
//這是String對象
String dee1=new String(dee);
//創建新的String對象de
System.out.println(dee1==dee);//結果為false
String de=dee1;
dee1="你好婷婷";
System.out.println(dee1==de);//結果為false
結論: String對象de創建時開辟一個新的空間,並且將dee的字符串賦值到de。String對象也是不能更改的,多次修改只會浪費更多的堆內存。
String Buffer和String Builder:
在我們平時寫程序的時候,不免會遇到對String對象的修改,特別是在制作一個GUI程序,會多次使用String對象的方法和對它的修改,於是Java提供了String Buffer和String Builder兩個類。
(1)String Buffer和String Builder它們都是可以對String對象修改,且不會創建一個新的堆內存(避免多次修改String對象對內存的極大浪費)。
(2)但是String builder、String buffer類與String類,它們三者不是一個類型的類,並且前兩個比String類大個級別(不是個類型就不能直接比較)。
所以實例化它的時候可以直接賦值
//(1)修改
StringBuilder de=new StringBuilder("你好世界你好世界");
de.replace(0, de.length(), "修改以后的值");//替換字符串
System.out.println(de);
//(2)轉換
StringBuilder de=new StringBuilder("你好世界"); String dee=de+""; //將StringBuilder轉換成String
StringBuffer de1=new StringBuffer(dee);
//將dee類型轉換成Stringbuffer類型
String Buffer和String Builder常用方法:
1.append(String e)
追加字符串:在原有的字符串后面繼續添加。
StringBuilder de=new StringBuilder("你好世界"); de.append( ":修改以后的值");//追加 System.out.println(de);//輸出結果:你好世界:修改以后的值
擴展:appendcodePoint(int cp):追加一個代碼點,並將其轉換為一個或兩個代碼單元並返回this
2.delete(int start , int end)
移除序列以內的字符串。
StringBuilder de=new StringBuilder("你好世界"); de.delete(0,de.length());//完全移除 System.out.println(de);
3.replace(int start , int end ,String e)
替換序列以內的字符串
StringBuffer de=new StringBuffer("你好世界"); de.replace(0,de.length(),"你好婷婷");//完全替換 System.out.println(de);//輸出結果:你好婷婷
擴展:setCharAt(int i, char c):將第 i 個代碼單元設置為 c(可以理解為替換)
4.insert(int e,String s)
插入字符串:根據序列號,在序列號對應的字符串后面插入新的字符串
StringBuffer de=new StringBuffer("你好世界"); de.insert(5,"你好婷婷");//插入 System.out.println(de); //輸出結果:程序報錯,因為序列號是5,但de里面沒有第5個
5.reverse()
取反:將字符串全部反轉形式取代
StringBuffer de=new StringBuffer("你好世界"); de.reverse();//fanhuan反轉 System.out.println(de);//結果:界世好你
String Buffer和String Builder的不同之處:
StringBuffer:可變字符串、效率低、線程安全;
StringBuilder:可變字符序列、效率高、線程不安全;
參考:
https://blog.csdn.net/weixin_38405253/article/details/100151578
https://blog.csdn.net/weixin_41101173/article/details/79677982