String與StringBuffer
阿新 • • 發佈:2018-12-19
1.String類
- String物件代表不可變的Unicode字元序列,因此可以將String物件成為“不可變物件”;
- 字串內容全部儲存到value[]陣列中,而變數value是final型別的,也就是常量(只能被初始化一次),這是“不可變物件”的典型定義方式 subString()是字串的擷取操作 在遇到字串常量之間的拼接時,編譯器會做出優化,在編譯期間就會完成字串的拼接,因此,在使用“==”進行String物件之間的比較時,要特別注意 常量池:是指在編譯期被確定,並被儲存在已編譯的.class檔案中的一些資料,它包括了關於類、方法、介面等中的常量,也包括字串常量。
例1:
public static void main(String[] args) { String str1 = "abcde"; String str2 = "abcde"; System.out.println(Integer.toHexString(str1.hashCode())); System.out.println(Integer.toHexString(str2.hashCode())); str1 = str1+"fg"; System.out.println(Integer.toHexString(str1.hashCode())); }
執行結果:
記憶體分析:
例2:
public static void main(String[] args) { String str1 = "hello"; String str2 = "world"; String str3 = "helloworld"; System.out.println(str1+str2); System.out.println(str3); System.out.println(str3 == (str1+str2)); System.out.println(str3.equals(str1+str2)); System.out.println(str3 == ("hello"+"world")); }
Java中直接使用" == "比較的是兩個字串的引用地址; equals方法比較兩字串的內容;
執行結果:
記憶體分析:
例3:
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); String str3 = "he"+"llo"; String str4 = new String("he")+new String("llo"); System.out.println(str1 == str2); //false; System.out.println(str1 == str3); //true; System.out.println(str3 == str2); //false; System.out.println(str4 == str3); //false; }
執行結果:
記憶體分析:
- str1 :在編譯時被放在類檔案常量池中;
- str2 :在堆中產生一個新的物件;
- str3 :字串拼接在編譯時完成,此時常量池已經有一個str1指向的“hello”,str3直接指向常量池中的“hello”;
- str4:先在堆中各自產生一個物件,最後產生一個新的物件,地址存放在str4中
例4:
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = "hello";
System.out.println(str1 == str2);//false
String str3 = "he"+new String("llo");
System.out.println(str1 == str3);
System.out.println(str2 == str3);
String str4 = "he"+"llo";
System.out.println(str4 == str2);
char[] array = {'h','e','l','l','o'};
String str5 = new String(array);
System.out.println("=============");
System.out.println(str1 == str5);
System.out.println(str2 == str5);
System.out.println(str3 == str5);
System.out.println(str4 == str5);
}
執行結果:
記憶體分析:
例5:
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("Hello");
System.out.println(stringBuffer);
System.out.println(Integer.toHexString(stringBuffer.hashCode()));
stringBuffer.append("world");//追加
System.out.println(stringBuffer);
System.out.println(Integer.toHexString(stringBuffer.hashCode()));
System.out.println("=============stringBuilder==============");
StringBuilder stringBuilder = new StringBuilder("Hi");
System.out.println("java");
System.out.println(Integer.toHexString(stringBuilder.hashCode()));
stringBuilder.append("world");//追加
System.out.println(stringBuilder);
System.out.println(Integer.toHexString(stringBuilder.hashCode()));
}
執行結果:
例6:
2.StringBuffer和StringBuilder
StringBuffer和StringBuilder非常類似,均代表可變的字元序列,這兩個類都是抽象類AbstractStringBuilder的子類,用法幾乎一模一樣
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
下面程式碼省略;
}
- AbstractStringBuilder內部也是一個字元陣列,但這個字元陣列沒有用final修飾,隨時可以修改,所以StringBuilder和StringBuffer稱為“可變字元陣列”
- StringBuilder和StringBuffer的區別 (1)StringBuffer是JDK1.0提供的類,執行緒安全,做執行緒同步檢查(單執行緒),效率低; (2)StringBuilder是JDK1.5提供的類,執行緒不安全,不做執行緒同步檢查(多執行緒),因此效率較高。
- StringBuilder的常用方法: 1.過載的public StringBuilder append(…)方法 可以為該StringBuilder物件新增字元序列,仍然返回自身物件 2.方法public StringBuilder delete(int start,int end) 可以刪除從start開始到end-1為止的一段字元序列,仍然返回自身物件 3.方法public StringBuilder deleteCharAt(int index) 移除此序列指定位置上的char,仍然返回自身物件 4.過載的public StringBuilder insert(…)方法 可以為該StringBuilder物件指定位置插入字元序列,仍然返回自身物件 5.方法public StringBuilder reverse() 用於將字元序列逆序,仍然返回自身物件 6.方法public String toString() 返回此序列中資料的字串表示形式
和String類類似的方法: public int indexOf(String str) public int indexOf(String str,int fromIndex) public String substring(int start) public String substring(int start,int end) public int length() char charAt(int index)