標籤:bsp als Block Storage limit void app content 知識 包含
字串是程式開發中使用最為頻繁,因此為了工作的高效和作為一名想進階的程式員,瞭解並掌握字串的處理顯得尤為重要。java為我們提供了String、StringBuffer、StringBuilde三個處理字串的類,下面我們對其做一個總結和介紹。
1、分別介紹
1)String
解答1:
我們在查看API文檔的時候,會發現有這麼一句話“字串是常量,它們的值在建立之後不能更改”。眾所周知常量是用final修飾的,一旦建立在程式的其他地方無法修改。這時我們就會快速的回想,在我們日常的開發中String是可以隨時隨地可對其賦值的,難道是jdk的API文檔寫錯了?其實不然,下面我們對其原理進行講解。
public static void main(String arg[]){
String str1 = "a";
String str2 = str1;
String str4 = str2;
System.out.println(str1 == str2);//true,說明引用stt1和引用str2指向了同一地址
String str3 = "b";
str1 = str1 + str3;
System.out.println(str1 == str2);//false,說明引用str1所指向的地址已經改變
System.out.println(str2 == str4);//true
str2 = str2 + str3;
System.out.println(str2 == str4);//false,說明引用str2所指向的地址已經改變
System.out.println(str1 == str2);//false
}
因為String是參考型別,參考型別在記憶體中的儲存如
也就是說,當我們在對str1做改變的時候,只是改變了其在棧記憶體中儲存的引用所指向的地址,與此同時java虛擬機器會為其在堆記憶體中重新分配新的空間,而原來堆記憶體位址儲存的值(因為是常量)並沒有發生改變,會作為無用的引用被java資源回收筒處理,到此相信可以順利理解上述代碼。
解答2:
public class Test {
private final static String s1 = "abc";
private final static String s2 = "abc";
public static void main(String arg[]){
String str1="abc";
String str2="abc";
String str3="ab"+"c";
String str4=new String(str2);
System.out.println(str1 == str2);//true,說明str1、str2指向同一地址
System.out.println(str1 == str3);//true,說明str1、str3指向同一地址
System.out.println(str1 == str4);//false,說明str1、str4指向不同的地址
System.out.println(s1 == s2);//true,說明s1、s2指向同一地址
System.out.println(str1 == s1);//true,說明str1、s1指向同一地址
}
}
上述現象是有常量在記憶體中的儲存規則決定的,java代碼在編譯的階段會在堆中分配出一Block Storage地區,作為常量池,用於儲存常量值。當再有常量被申明時,編譯器會去常量池中尋找這個字串是否存在,若存在則將這個字串的引用直接指向字串所在地址,否則為其在常量池中分配新的空間,也就是說所有值相同的常量的引用會指向同一個儲存地址。至於str4是編譯器為其new了新的儲存空間,將其作為對象處理,而不是常量。
下面給出常量的記憶體中的儲存分配
解答3:String的常用方法
equals(Object anObject)和equalsIgnoreCase(String anotherString):equals是開發中使用非常頻繁的方法,需要區分equals和“==”所比較的對象,equals比較的是兩個對象(引用)的值是否相等,“==”比較的對象既可以是基礎資料型別 (Elementary Data Type),也可以是參考型別,當比較對象為基礎資料型別 (Elementary Data Type)時就是值的比較,當比較對象是參考型別的時候比較的是引用(引用所指的地址),而不是引用所指向的值。後者是不考慮大小寫比較。
contentEquals(CharSequence cs)、contentEquals(StringBuffer sb):字串與指定的CharSequence/StringBuffer比較。
compareTo(String anotherString)
和compareToIgnoreCase(String str)
:按字典順序比較兩個字串,後者忽略大小寫。
matches(String regex):當前字串是否匹配給定的Regex。
length():返回次字串的長度
isEmpty():若且唯若 length()
為 0 時返回 true。
split(String regex)、split(String regex, int limit)
:據給定Regex拆分字串
substring(int beginIndex)
、substring(int beginIndex, int endIndex):按規則返回此字串的子字串
replace(char oldChar, char newChar)、replace(CharSequence target, CharSequence replacement)、replaceAll(String regex, String replacement):替換
valueOf(boolean b)等:返回基礎資料型別 (Elementary Data Type)的字串表示形式
valueOf(Object obj):返回Object的字串形式
toLowerCase()和toUpperCase():使用預設語言環境將此字串中的所有字元轉換為小寫/大寫
toCharArray():將字串轉為字元數組
contains(CharSequence s)
:若且唯若字串包含指定的char值序列時返回true。
indexOf(int ch)
、indexOf(int ch, int fromIndex)
、indexOf(String str)
、indexOf(String str, int fromIndex)
:按規則返回索引。
lastIndexOf(int ch)
、lastIndexOf(int ch, int fromIndex)、lastIndexOf(String str)、lastIndexOf(String str, int fromIndex):按規則返回指定字元或字串最後出現位置的索引。
concat(String str):指定字串串連到此字串的結尾。(一般用+號解決了,所以用的很少)
2)StringBuffer
安全執行緒的可變字元序列。
append(String str)等:將字串追加到此字串後面
insert(int offset, String str)等:將字串插入此字元序列中
reverse():將此字元序列用其反轉形式取代。這是一個非常有用的方法,可方便的將指定字串逆序輸出。
toString():將StringBuffer串轉換為String
3)StringBuilde
一個可變的字元序列,基本和StringBuffer相同,但是是非安全執行緒的,所以效率高於StringBuffer、Stringj。
2、String、StringBuilde、StringBuffer比較
1、StringBuilde是非安全執行緒的,StringBuffer是安全執行緒的。
2、效率上String<StringBuffer<StringBuilde
原因在於String是字串常量,另外兩個是字串變數,String在每次賦值時都需要new一個新的對象(上面有詳細介紹),原有對象會被GC當記憶體回收,會大大降低執行效率。而StringBuffer與StringBuilder是字串變數,改變發生在同一對象,少了建立、銷毀對象環節。
最後建議,如果操作少量資料則使用String,如果單線程下操作大量資料則用StringBuilder,如果是多線程下操作大量資料則用StringBuffer。
java從基礎知識(二)字串處理