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

这样节省了一个对象引用和一点点时间。

我的观点,若有问题,欢迎留言交流~

相关文章
相关标签/搜索