java中String類型的相關知識總結 一、常用方法: 1.構造方法: byte數組 可指定offset和length 可指定charset char數組 可指定offset和count 字元序列 String StringBuffer StrngBuilder 2. 實例方法: 獲取字元/碼點/ ...
java中String類型的相關知識總結
一、常用方法:
1.構造方法:
-
byte數組
-
可指定offset和length
-
可指定charset
-
-
char數組
- 可指定offset和count
-
字元序列
- String
- StringBuffer
- StrngBuilder
2. 實例方法:
- 獲取字元/碼點/位元組
charAt(int index) char
codePointAt(int index) int
getBytes() byte[]
getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin) void
toCharArray() char[]
- 長度
length() int
codePointCount(int beginIndex,int endIndex) int
- 字元串操作
concat(String str) String
substring(int beginIndex,int endIndex) String
split(String regex) String[]
trim() String
toUpperCase()/toLowerCase String
replace(char oldChar,char newChar) String
replace(CharSequence target,CharSquence replacement) String
replaceAll(String regex,String replacement) String
replaceFirst(String regex,String replacement) String
- 判斷
contains(CharSequence s) boolean
endsWith(String suffix)/startsWith(String prefix) boolean
equals(Object anObject) boolean
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
matches(String regex) boolean
- 序號
indexOf(int ch/String str)/lastIndexOf()
3. 靜態方法:
String.format(String format,Obect... args) String
String.valueOf(xxx) String
二、底層實現:
jdk1.8中String類型底層就是一個char數組:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
三、不可變性:
String最為人所津津樂道的便是它的不可變性(immutable),這裡就引出兩個問題,String如何做到不可變的,以及不可變的好處
1. 如何實現不可變:
jdk1.8中String的字元存儲在一個char數組裡
- char數組final,不可變
- 沒有提供任何可以修改數組內容的方法
2. 不可變的好處:
- 不可變,線程絕對安全
- 作為參數不可變,更安全
- 字元串常量池的需要,可以共用而不用擔心被誰改變
- hash值不可變,只要算一次,可以緩存hash
3. String和StringBuffer和StringBuilder的區別:
-
String不可變,線程安全
-
StringBuffer可變,線程安全
-
StringBuilder可變,線程不安全
四、緩存池:
1.字元串常量池(String pool)里存放著所有的字元串字面量
String a="aaa";
String b="aaa";
//a,b引用到的String pool里的同一個對象
a==b//true
2. new 出來的String對象放在堆區
String a=new String("aaa");
String b=new String("aaa");
a==b//false
a=="aaa"//false
//這裡實際是先創建字面量"aaa",再去創建對象的
new創建字元串時首先查看池中是否有相同值的字元串,如果有,則拷貝一份到堆中,然後返回堆中的地址;如果池中沒有,則在堆中創建一份,然後返回堆中的地址(註意,此時不需要從堆中複製到池中,否則,將使得堆中的字元串永遠是池中的子集,導致浪費池的空間)!
-
關於
String str=new String("123")
創建了幾個對象的問題 很顯然,new只調用了一次,也就是說只創建了一個對象。而這道題目讓人混淆的地方就是這裡,這段代碼在運行期間確實只創建了一個對象,即在堆上創建了"abc"對象。而為什麼大家都在說是2個對象呢,這裡面要澄清一個概念,該段代碼執行過程和類的載入過程是有區別的。在類載入的過程中,確實在運行時常量池中創建了一個"abc"對象,而在代碼執行過程中確實只創建了一個String對象(堆上)。
-
public String(String original) { this.value = original.value; this.hash = original.hash; }
3. intern()方法
先判斷字元串常量池裡是否已經有了這個字元串,如果有就返回常量池中該字元串的引用,沒有就在常量池中添加並返回常量池中的引用。
String a=new String("aaa");
a=="aaa"//false
a=a.intern()
a=="aaa"//true
五、參考資料
鄙人只是一名在讀的軟體工程專業的本科生,正在複習找工作,故而將複習時遇到的一些有意思的東西總結出來,既是加深理解,也是便於日後複習。
鄙人才疏學淺,若文中有謬誤之處,還望諸位不吝斧正,以免誤人子弟。若有同道中人想一同討論學習,也可以聯繫我=>[email protected]。未經作者允許,請勿轉載!
路漫漫其修遠兮,吾將上下而求索。