Java核心技術
95 篇文章16 訂閱
訂閱專欄
标題中的substring方法指的是字元串的substring(int beginIndex, int endIndex)方法,這個方法在jdk6,7是有差異的。
substring有什麼用?
substring傳回的是字元串索引位置beginIndex開始,endIndex-1結束的字元串。
來看這個例子:
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
輸出:
bc
下面看看在JDK之間,它們的實作原理有什麼不一樣,及值得注意的地方。
JDK 6
String背後是由char數組構成的,在JDK6中,String包含三個字段:char value[], int offset, int count,意思很簡單。
substring被調用時,它會建立一個新的字元串,但字元串的值還指向堆中同樣的字元數組。它們的差別隻是數量和下标引用不一樣,如圖所示。
JDK6中的部分源碼可以說明這個問題。
//JDK 6
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
//check boundary
return new String(offset + beginIndex, endIndex - beginIndex, value);
}
會有什麼問題?
如果一個很長的字元串,但是每次使用substring(),你隻需要很小的一部分。這将會導緻性能問題,因為隻需要一小部分,卻引用了整個字元數組内容。對于JDK 6,解決方案是使用以下内容:
x = x.substring(x, y) + ""
DK 7,8
JDK6這種問題在JDK7+中已經改善了,JDK7+中實際是重新建立了一個字元數組,如圖。
JDK7中的部分源碼,JDK8類似。
//JDK 7
public String(char value[], int offset, int count) {
//check boundary
this.value = Arrays.copyOfRange(value, offset, offset + count);
}
public String substring(int beginIndex, int endIndex) {
//check boundary
int subLen = endIndex - beginIndex;
return new String(value, beginIndex, subLen);
}
對于JDK的這種差異,我們知道就好,現在應該都是JDK7及8了吧,其實對于小字元串的這種操作性能也是可以忽略不計的。