标签:
substring(int beginIndex, int endIndex)方法在JDK6和JDK7是不一样的,了解两个版本实现它的不同能让你更好地运用它们。
1、substring()的作用是什么?
substring(int beginIndex, int endIndex) 方法返回一个起始位置是beginIndex(包含),结束位置是endIndex-1(包含)的一个字符串。例如:
Input:
String x = "abcdef"; x = x.substring(1,3); System.out.println(x);
Output:
bc
2、当substring()方法被调用时发生了什么?
你可能知道x是不可变的,当x指向x.substring(1,3)的结果后,它实际上指向一个完全新的字符串如下:

然而,这张图并不准确或者它表现的是堆里面真正发生了什么。那当substring()方法被调用时,JDK6和JDK7真正发生了什么不同呢
3、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);
}
4、在JDK6的substring()的问题
如果你有很长的字符串,但你每次调用substring()仅仅需要一小部分时,这会引起性能问题。因为你仅仅需要一部分,却要保持整个空间。对于JDK6,下面是一个解决方法,这能让它指向真正的子串:
x = x.substring(x, y) + ""
5、在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));
这样节省了一个对象引用和一点点时间。
个人观点,如有问题,欢迎留言交流~
substring()方法在JDK6和JDK7的不同 (翻译外文博客)
标签:
原文地址:http://my.oschina.net/dailongyao/blog/518946