1.前言
2.什麼是字串(String)
3.字串(String)的兩種建立方式及其區別
4.字串(String)的方法及其部分原碼解析
5.字串(String)的弊端
String 類代表字串。Java 程式中的所有字串字面值(如 "abc" )都作為此類的範例實現。
字串是常數;它們的值在建立之後不能更改。字串緩衝區支援可變的字串。因為 String 物件是不可變的,所以可以共用
String類表示字串,在建立之後不能被更改,可用於檢查序列的單個字元,搜尋字串,提取字串,建立字串副本並將所有字串全部轉換為大寫或小寫。
字串有兩種建立方式,分別為直接賦值和構造方法。
字串在建立之後便不會被更改,對於字串內容的操作都會新建立一個字串物件
以雙引號內的資料作為字串儲存的資料
String str="hello world";
初始化一個新建立的 String 物件,使其表示一個空字元序列
String str1=new String();
String str2=new String();
String str3=null;
空字串和null的值都為空
空字串表示字串物件參照的值為空,如上str2的值為空,str1指向字串的記憶體空間
null表示參照為空,如上str3的參照為空,str3沒有指向任何空間
在實際中作用
對字串的校驗過程中,要考慮字串值的兩種"空",既要考慮字串參照物件值是否為空,又要考慮參照物件是否為空
初始化一個新建立的 String 物件,使其表示一個與引數相同的字元序列;換句話說,新建立的字串是該引數字串的副本
String str4=new String("hello world");
生成的str4是對應引數字串的副本,但str4是對應新建立的物件
分配一個新的 String,使其表示字元陣列引數中當前包含的字元序列
char[] chars={'a','b','c'};
String str5=new String(chars);
適用場景:用於改變字串的資料
由於字串在建立之後不能被修改,而字串沒有相應的改變字串的方法,但是由獲取對應索引的資料和將資料轉化為字元陣列的形式,通過該構造方法可以將字串的資料進行修改
通過使用平臺的預設字元集解碼指定的 byte 陣列,構造一個新的 String
byte[] bytes={97,98,99};
String str6=new String(bytes);
使用場景:用於網路中的資料傳輸,將位元組資訊轉化為字串時使用
網路中的資料是位元組型別,通過該方法可以將位元組資訊轉化為字串形式再進行處理
直接賦值:直接賦值進入棧記憶體中,會進入堆記憶體的串池中檢視是否有相同地址的資料,沒有便建立,有的話便複用
構造方法:每new一次便會在堆記憶體中開闢一個新的空間,生成新物件,不同物件的地址不同
結果為
== 用於比較地址是否相等,equals用於比較具體的值
給定物件表示的 String 與此 String 相等,則返回 true;否則返回 false
原始碼解釋
public boolean equals(Object anObject) {
//比較當前物件(this)與給定物件(anObject)的地址是否相等
if (this == anObject) {
return true;
}
//判斷anObject是否是String的範例
if (anObject instanceof String) {
//將anObject強制轉化為String
String anotherString = (String)anObject;
//獲取當前物件對應的字元資料的長度
int n = value.length;
//判斷n與給定物件對應的字元陣列的長度是否相等
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;
}
返回指定索引處的 char 值。索引範圍為從 0 到 length() - 1。序列的第一個 char 值位於索引 0 處,第二個位於索引 1 處,依此類推,這類似於陣列索引
public char charAt(int index) {
//判斷index是否在給定的索引範圍之內,若不在則丟擲字串角標越界
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
//如果在對應的範圍內,則獲取對應的字元陣列對應縮影的資料
return value[index];
}
返回此字串的長度
public int length() {
//返回對應物件字元陣列的長度
return value.length;
}
將指定字串連線到此字串的結尾。
如果引數字串的長度為 0,則返回此 String 物件。否則,建立一個新的 String 物件,用來表示由此 String 物件表示的字元序列和引數字串表示的字元序列連線而成的字元序列
public String concat(String str) {
//判斷str是否為空
if (str.isEmpty()) {
return this;
}
int len = value.length;
int otherLen = str.length();
//複製當前物件的值,並指定長度為len+otherLen
char buf[] = Arrays.copyOf(value, len + otherLen);
//將str的值新增到buf之後,getChars()的底層是System的arraycopy()
str.getChars(buf, len);
return new String(buf, true);
}
通常使用"+",和concat()的底層原理是一樣
返回一個新字串,它是此字串的一個子字串。該子字串從指定的 beginIndex 處開始,直到索引 endIndex - 1 處的字元。因此,該子字串的長度為 endIndex-beginIndex
public String substring(int beginIndex, int endIndex) {
//判斷給定的起始索引和終止索引是否符合要求
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
//判斷終止索引是否大於起始索引
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
//判斷起始索引和終止索引是否對應於字串對應的字元陣列的起始位置和終止位置,如果是,便返回對應的字串,否則便返回索引的資料
return ((beginIndex == 0) && (endIndex == value.length)) ? this: new String(value, beginIndex, subLen);
}
方法的過載
public String substring(int beginIndex)
返回一個新的字串,它是此字串的一個子字串。該子字串從指定索引處的字元開始,直到此字串末尾。
返回一個新的字串,它是通過用 newChar 替換此字串中出現的所有 oldChar 得到的。
如果 oldChar 在此 String 物件表示的字元序列中沒有出現,則返回對此 String 物件的參照。否則,建立一個新的 String 物件,它所表示的字元序列除了所有的 oldChar 都被替換為 newChar 之外,與此 String 物件表示的字元序列相同
public String replace(CharSequence target, CharSequence replacement) {
//運用正規表示式對字串進行替換
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
由於字串一旦建立後便不能更改,因此在進行字串的拼接過程中,會不斷產生新的物件,對於記憶體的消耗大,同時,進行字串的反轉,過程複雜,記憶體的消耗大,因此需要其他的字串類