substring(int beginIndex, int endIndex)方法在JDK6和JDK7中是不同的。瞭解他們的區別可以讓我們更好的使用這個方法。方便起見,以下用substring() 代替 substring(int beginIndex, int endIndex)。
1. substring()做了什麼?
substring(int beginIndex, int endIndex)方法返回一個以beginIndex開頭,以endIndex-1結尾的String物件。
String x ="abcdef"; x =x.substring(1,3); System.out.println(x);
輸出:
bc
2.當substring()被呼叫的時候發生了什麼?
也許你覺得,因為x是不可變的,當x經過substring(1,3)處理以後,會指向如下一個全新的String物件:
然而,這張圖沒有正確的表示出堆記憶體裡真正發生了什麼。那麼當呼叫substring()方法時,JDK6和JDK7究竟有什麼不同呢。
3. JDK 6中的substring()
String是由一個字元陣列實現的,在JDK6中,String類由三部分組成:charvalue[], int offset, int count.。他們才是真正用來儲存字元的陣列,陣列的第一個元素用來儲存字元的長度。
當呼叫substring()方法時,會建立一個新的String物件,但是這個String物件的值仍然指向堆記憶體中相同的陣列。真正不同的是它們的計數和偏移量。
下面的程式碼已經做了簡化,只包含解釋這一問題的關鍵部分。
//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); }
4.JDK 6中的substring()存在的一個問題
如果有一個非常長的String物件,但是你每次通過substring()只用到其中一小部分。這樣就會有一個效能上的問題,對於JDK6來說,使用以下程式碼可以解決這個問題,這樣做會建立一個真正的子字串物件:
x = x.substring(x, y) + ""
5. JDK 7中的substring()
在JDK7中,substring()方法實際上會在堆記憶體中建立一個新的陣列,這是JDK7中的一項改進。
//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); }
原文地址:
http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/