substring()方法在JDK6和JDK7的不一樣 (翻譯外文博客)

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));

這樣節省了一個對象引用和一點點時間。

我的觀點,若有問題,歡迎留言交流~

相關文章
相關標籤/搜索