Java基礎學習筆記(七)—— java中的字符串池與可變字符串

Java基礎學習筆記(七)—— java中的可變字符串與字符串池

Life was like a box of chocolates, you never know what you’re gonna get.

| @Author:TTODS


Java中的字符串池(String Pool)

我們在獲得字符串對象的時候,有兩種方法:
①、使用字符串常量賦值的方法
②、創建對象的通用方法,即new一個對象

String str = "Hello, World!"; //方法①
String str1 = new String("Hello, World!"); //方法②

那麼這兩種方法創建的字符串有區別嗎?且看下一段代碼

String s7 = new String("Hello");
String s8 = new String("Hello");
String s9 = "Hello";
String s10 ="Hello";

System.out.println("s7==s8:"+(s7==s8));
System.out.println("s9==s10:"+(s9==s10));
System.out.println("s7==s9:"+(s7==s9));
System.out.println("s7==s10:"+(s7==s10));
s7==s8:false
s9==s10:true
s7==s9:false
s7==s10:false

通過上例可以看出在使用==對上面四個字符串對象進行比較時,只有s9與s10比較時,結果時true,其他比較結果都是false,前面已經說過了在使用==對引用數據類型 進行比較時,實際比較的是其在內存中的首地址,即判斷比較的兩個數據是否爲同一對象,也就是說上面的s9與s10其實是一個對象。
這是爲什麼?Java中的不可變字符串String常量,採用字符串池(String Pool)管理技術,字符串池是一種字符串駐留技術。採用字符串常量賦值時(方法①),會在字符串池中查找"Hello"字符串常量,如果已經存在把引用賦值給s9,否則創建"Hello"字符串對象,並放到池中。根據此原理,可以推定s10與s9是相同的引用,指向同一個對象。但此原理並不適用於new所創建的字符串對象,在使用new創建字符串對象時,會創建"Hello"字符串對象,而它並沒有放到字符串池中。也就是說上例中的s7和s8是兩個不同的引用,指向不同的對象。
在這裏插入圖片描述

上例與本圖來自源於《java從小白到大牛》

java中的可變字符串 StringBuffer與StringBuilder

StringBuffer和StringBuilder都是java中的可變字符串,中文翻譯爲"字符緩衝區",它們完全相同的API,唯一的區別就是StringBuffer是線程安全的,StringBuilder不是線程安全的,但它的執行效率很高。

構造方法
StringBuilder()

構造一個沒有字符的字符串構建器,初始容量爲16個字符。

StringBuilder sbuilder = new StringBuilder();
System.out.println(sbuilder.capacity());//輸出16
StringBuilder(CharSequence seq)
StringBuilder sbuilder = new StringBuilder("Hello, World!");
System.out.println(sbuilder);//輸出Hello, World
StringBuilder(int capacity)
StringBuilder sbuilder = new StringBuilder(32);
System.out.println(sbuilder.capacity());//輸出32
StringBuilder(String str)
String str = "Hello, World!";
StringBuilder sbuilder = new StringBuilder(str);
System.out.println(sbuilder);//輸出Hello, World
常用方法(一些與String相同的方法參考上篇筆記 )

關於下面的方法的更多重構方法請參考官方文檔

append

將一個字符串(也可將其他類型轉化成字符串類型)拼接到此字符串的尾部

StringBuilder sbuilder  = new StringBuilder("Hello, World!");
sbuilder.append(" Hello, TTODS.");
System.out.println(sbuilder);//輸出Hello, World! Hello, TTODS.
capacity

返回當前容量。 容量是新插入字符可用的存儲量,超過此值將進行分配。

delete(int start, int end)

刪除指定索引區間[start,end)的字符,如果start爲負數或者start大於end,會報錯StringIndexOutOfBoundsException

StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.delete(0,4);
System.out.println(sbuilder);//輸出456789
deleteCharAt

刪除指定索引處的字符

StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.deleteCharAt(4);
System.out.println(sbuilder);//012356789
replace(int start,int end,String str)

用字符串str替換原字符串中指定的內容

StringBuilder sbuilder  = new StringBuilder("0123456789");
String str ="-----";
sbuilder.replace(1, 3, str);
System.out.println(sbuilder); // 輸出 0-----3456789
insert(int index,char[] str,int offset,int len)

在指定位置插入字符數組中指定的內容

StringBuilder sbuilder  = new StringBuilder("0123456789");
char[] chs = {'1','2','3','4','5','6'};
sbuilder.insert(10,chs,0,6);
System.out.println(sbuilder);//輸出 0123456789123456
reverse

反轉字符串

StringBuilder sbuilder  = new StringBuilder("0123456789");
System.out.println(sbuilder);// 輸出 0123456789
sbuilder.reverse();
System.out.println(sbuilder);// 輸出 9876543210
setCharAt
StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.setCharAt(4, '6');
System.out.println(sbuilder);//輸出 0123656789
setLength

設置字符串的長度,參數爲設定的新長度,當新長度爲負數時,會報錯IndexOutOfBoundsException

StringBuilder sbuilder  = new StringBuilder("0123456789");
StringBuilder sbuilder1  = new StringBuilder("0123456789");
sbuilder.setLength(5);
System.out.println(sbuilder);
System.out.println(sbuilder.length());
sbuilder1.setLength(15); //當新長度大於原長度時,將用字符'\u0000'填充
System.out.println(sbuilder1);
System.out.println(sbuilder1.length());

輸出

01234
5
0123456789
再談String、StringBuilder和StringBuffer

之前已經講過了String是final類,String對象一旦創建內容是不能修改的,即所有修改內容的方法,都是在「暗地裏」創建了新的對象,這樣就會產生許多的數據垃圾.所以我們如果需要頻繁修改字符串的值,應使用StringBuilder類和StringBuffer類.在考慮線程安全時推薦StringBuffer類,在不 考慮線程安全時,推薦使用StringBuilder類.
運行速度比較:StringBuilder>StringBuffer>String
StringBuilder不是線程安全的,但運行速度最快,StringBuffer是可以修改的,且線程安全,運行速度較快,String不可以修改,在對象的回收與創建時會耗費時間,速度最慢.

- THE END -
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章