String Buffer
Prerequisites:
字串存放位置
String Buffer繼承AbstractStringBuilder。
字串存放位置是在AbstractStringBuilder中的value變數,不是final,char[]陣列是物件,是存在Heap中。
1
2
3
4
char[] value;
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
String Buffer vs String
String存放字串的位置,是final的,所以更新字串,就是建立新的物件,因為final不能被修改內容。
String Buffer存放字串的位置,不是final,所以更新字串,是更新物件內容,因為不用重新建立物件,所以效率比較快。
建構子
StringBuffer的空建構子,預設建立char[16]的大小。
1
2
3
public StringBuffer() {
super(16);
}
可自訂char[]大小。
1
StringBuffer stringBuffer = new StringBuffer(100);
使用字串建立StringBuffer。
1
StringBuffer stringBuffer = new StringBuffer("Hello World");
建立char[字串長度 + 16]的大小。
1
2
3
4
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
append
append傳回值就是StringBuffer。
1
2
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = sb.append("abc");
會把基本型別,自動轉成字串。
1
2
3
StringBuffer sb = new StringBuffer();
sb.append(true).append(10.5).append(10);
System.out.println(sb);
true10.510
把boolean轉成字串原始碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public AbstractStringBuilder append(boolean b) {
ensureCapacityInternal(count + (b ? 4 : 5));
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
if (b) {
val[count++] = 't';
val[count++] = 'r';
val[count++] = 'u';
val[count++] = 'e';
} else {
val[count++] = 'f';
val[count++] = 'a';
val[count++] = 'l';
val[count++] = 's';
val[count++] = 'e';
}
}
StringBuffer轉String
使用toString()或者使用String建構子放入StringBuffer。
1
2
3
4
5
6
7
8
9
10
11
public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
// 使用toString()
String str1 = sb.toString();
// 使用String建構子
String str2 = new String(sb);
System.out.println(str1);
System.out.println(str2);
}
}
Hello World
Hello World
toString原始碼
重點是 new String(),new String是在heap建立記憶體空間,不是在String pool建立記憶體空間。
1
2
3
4
5
6
7
public synchronized String toString() {
if (toStringCache == null) {
return toStringCache = new String(this, null);
}
// 重點是 new String
return new String(toStringCache);
}
StringBuffer常用方法
delete
StringBuffer delete(int start, int end)
start <= range < end
range就是要刪的範圍,不包含end。
1
2
3
4
StringBuffer sb = new StringBuffer("Hello world,貓咪");
// 1 <= x < 4
sb.delete(1,4);
System.out.println(sb);
Ho world,貓咪
replace
修改可當作replace取代。
StringBuffer replace(int start, int end, String str)
start <= range < end
range就是要取代的範圍,不包含end。
1
2
3
StringBuffer sb = new StringBuffer("貓咪Hello world");
sb.replace(1, 4, "狗");
System.out.println(sb);
貓狗llo world
indexOf
第一次找到的位置,由左往右。
1
2
3
StringBuffer sb = new StringBuffer("貓咪Hello world");
int index = sb.indexOf("咪");
System.out.println(index);
1
insert
在指定位置插入字串,原本的位置往後移到插入字串的後面。
1
2
3
StringBuffer sb = new StringBuffer("貓咪Hello world");
sb.insert(1, "恐龍");
System.out.println(sb);
貓恐龍咪Hello world
length長度
1
2
StringBuffer sb = new StringBuffer("貓咪Hello world");
int len = sb.length();
null
建構子傳null
1
2
3
String str = null;
StringBuffer sb = new StringBuffer(str);
System.out.println(sb.length());
在父類別AbstractStringBuilder的建構子中,str.length()會拋出例外,因為str是null。
1
2
3
4
AbstractStringBuilder(String str) {
int length = str.length();
// ....
}
append傳null
先到父類別的appendNull()方法
1
2
3
4
5
6
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
// ....
}
appendNull,會把null的字串加在字元陣列中。
1
2
3
4
5
6
7
8
9
10
11
12
private AbstractStringBuilder appendNull() {
ensureCapacityInternal(count + 4);
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
val[count++] = 'n';
val[count++] = 'u';
val[count++] = 'l';
val[count++] = 'l';
} else {
// ....
}
以下執行結果為4
1
2
3
4
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);
System.out.println(sb.length());
4
lastIndexOf與insert進階
lastIndexOf是由最後面往前找,找到就傳回位置。
12345.67 轉成 12,345.67
1
2
3
4
5
6
StringBuffer sb = new StringBuffer("12345.67");
// 找到小數點
int index = sb.lastIndexOf(".");
// 小數點前三位逗號
sb.insert(index - 3, ",");
System.out.println(sb);
12,345.67
那如果前面的數字很長呢?例如:12345678910111213.11
1
2
3
4
5
6
7
StringBuffer sb = new StringBuffer("12345678910111213.11");
// -3要放在初始值。
int index = sb.lastIndexOf(".") - 3;
for (int i = index; i > 0; i -= 3) {
sb.insert(i, ",");
}
System.out.println(sb);
12,345,678,910,111,213.11