String:
- 是不可變的常量,不可變的好處是編輯器讓字符串共享,實際上只有用""聲明的字符串纔是共享的,存放在常量池中,使用new、subString、+等操作符生成的String字符串都不是共享的。
- 字符串的值比較使用的是equals(),不能使用==,==比較的是字符串地址,如果這個字符串在常量池中,那麼==比較的兩個引用的地址相等
- 直接使用“”聲明的字符串都存在常量池中(實現共享)
- String str1=”first”;
jvm在運行時先查找常量池中是否有該字符串,如果有則直接返回該字符串的引用給first(實現了字符串 的共享) ;否則先在常量 池中創建該字符串並返回引用。 此時只會在常量池中創建String對象,不會在堆中創建。 - String str2=new String(“second”);
該代碼生成了兩個String對象。因爲使用了“”會現在常量池中查找是否存在second對象,沒有則創建
否則不創建;在常量池創建完成後,由於使用了new,jvm會在堆中創建內容相同的String對象,並將引用
返回給str2. - String str3=”what”; String str4=str3+”a nice day”;
運行時,+ 相當於new,所以堆中會有“what a nice day”對象;常量池中會有”what” “a nice day”兩個對象,而不會有”what a nice day”對象。
字符串常量,字符串長度不可變。用於存放字符的數組被聲明爲final的,因此只能賦值一次,不可再更改。視頻裏主要講解String的內存構造,在java核心技術一書中我們知道最常用的String類方法有equals(),忽略大小寫比較內容equalsIgnoreCase(),返回子串subString(),字符串拼接+,除此之外還有toCharArray()、CharAt(index)、toUpperCase()、toLowerCase()
public class StringDemo {
public static void main(String[] args) {
//String--subString()
String s = "helloWorld";
System.out.println(s.substring(0,2));
String s1 = s + " ILoveTheWorld";
int age = 18;
String s2 = s + age;
System.out.println("拼接的結果:"+s1);
System.out.println("拼接的結果:"+s2);
String s3 = "helloWorld ILoveTheWorld";
//boolean--equals()
if(s1.equals(s2)){
System.out.println("s1 s2內容一致");
}
else{
System.out.println("s1 s2內容不一致");
}
if(s1.equalsIgnoreCase(s3)){
System.out.println("s1 與s3不區分大小寫的情況下內容一致");
}
//char[]--toCharArray() char--charAt()
String ss = "cscs";
char[] c = ss.toCharArray();
System.out.println(c);
System.out.println(ss.charAt(0));
//轉換大小寫
String xx = ss.toUpperCase();
System.out.println(xx);
System.out.println(xx.toLowerCase());
//將int、double、char、Boolean、Object等轉成String 靜態方法valueOf(各種類型)
int i = 0;
String zs = String.valueOf(i);
//boolean--endsWith(String)
String sss = "cs.java";
boolean b = sss.endsWith(".java");
System.out.println(b);
System.out.println(sss.concat("is Student"));
//在IO中使用的byte[] --getBytes()
byte[] by = sss.getBytes();
System.out.println(by);
}
}
StringBuffer和StringBuilder都j繼承了AbstractStringBuilder,使用了模板的設計模式,查看源碼可以發現,大部分的核心數據的操作都是放在父類中進行,子類中只實現了子類額外的功能。
StringBuffer:
字符串變量(Synchronized,即線程安全)。內部採用的是可變數組,不用final修飾,默認容量是16個字符,他的變長也是由於複製造成的,所以效率比String慢。如果要頻繁對字符串內容進行修改,出於效率考慮最好使用 StringBuffer,如果想轉成 String 類型,可以調用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 線程安全的可變字符序列。在任意時間點上它都包含某種特定的字符序列,但通過某些方法調用可以改變該序列的長度和內容。可將字符串緩衝區安全地用於多個線程。它的增刪改等方法中修飾符由synchronized的修飾。
構造函數:StringBuffer()和StringBuffer(String)底層存儲數據的Char[]數組,初始化時,該數組的長度是16。如果構造函數有新傳入字符轉str,則16基礎上加str.length.
字符串添加:
-->先檢查內部char[]數組是否需要擴容
-->如需要擴容則進行擴容,然後將原來元數據copy到新數組中。
-->再將新添加的元數據加入到新char[]數組中
StringBuilder:
字符串變量(非線程安全)底層結構和StringBuffer實現基本一樣,只是沒有做同步處理。
基本原則:
- 如果要操作少量的數據用 String ;
- 單線程操作大量數據用StringBuilder ;
- 多線程操作大量數據,用StringBuffer。
StringBuffer的六種基本操作:
- append()
- length()
- insert()
- replace()
- reverse()
- toString()