substring(int beginIndex, int endIndex)方法在JDK6和JDK7是不同的,瞭解兩個版本實現它的不一樣能讓你更好地運用它們。
java
一、substring()的做用是什麼?數組
substring(int beginIndex, int endIndex) 方法返回一個起始位置是beginIndex(包含),結束位置是endIndex-1(包含)的一個字符串。例如:app
Input:性能
String x = "abcdef"; x = x.substring(1,3); System.out.println(x);
Output:ui
bcthis
二、當substring()方法被調用時發生了什麼?
spa
你可能知道x是不可變的,當x指向x.substring(1,3)的結果後,它實際上指向一個徹底新的字符串以下:code
然而,這張圖並不許確或者它表現的是堆裏面真正發生了什麼。那當substring()方法被調用時,JDK6和JDK7真正發生了什麼不一樣呢對象
三、substring() 在 JDK6字符串
String 是由字符數組表現的。在JDK6,String 類包含3個字段:char value[],int offset,int count. 它們用來存儲真正的字母數組,數組的第一個座標,String當中字母的數量。
當substring()被調用時,它建立了一個新的字符串,可是在堆中字符串的值仍是指向一樣的數組。兩個字符串不一樣的只是count和offset的值。
下面的代碼簡化而且是關鍵地說明這個問題
//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); }
四、在JDK6的substring()的問題
若是你有很長的字符串,但你每次調用substring()僅僅須要一小部分時,這會引發性能問題。由於你僅僅須要一部分,卻要保持整個空間。對於JDK6,下面是一個解決方法,這能讓它指向真正的子串:
x = x.substring(x, y) + ""
五、在JDK7中的substring()
在JDK7有改進,在JDK7中,substring()方法真正在堆中建立了一個新數組
//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/)
針對第四點,我的補充一下:
x = x.substring(x, y) + ""
上述代碼實現過程以下:
StringBuilder sb = new StringBuilder(); sb.append(x.substring(x, y)); sb.append(""); x = sb.toString();
用下面的方法代替:
x = new String(x.substring(x, y));
這樣節省了一個對象引用和一點點時間。
我的觀點,若有問題,歡迎留言交流~