天天看點

注意:字元串substring方法在jkd6,7,8中的差異。

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被調用時,它會建立一個新的字元串,但字元串的值還指向堆中同樣的字元數組。它們的差別隻是數量和下标引用不一樣,如圖所示。

注意:字元串substring方法在jkd6,7,8中的差異。

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+中實際是重新建立了一個字元數組,如圖。

注意:字元串substring方法在jkd6,7,8中的差異。

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了吧,其實對于小字元串的這種操作性能也是可以忽略不計的。