您的位置:首页 > 编程语言 > Java开发

Simple Java—Strings and Arrays(二)substring()在jdk6和jdk7中的不同

2016-01-24 22:37 489 查看
Translate from Simple java

substring(int beginIndex,int endIndex)方法在jdk6和jdk7中是不同的。知道这个不同可以帮助我们更好的http://www.programcreek.com/simple-java/使用这个方法。出于简单的目的,下文中的substring()代表substring(int beginIndex,int endIndex)这个方法

1. substring()做了什么?

substring(int beginIndex,int endIndex)方法返回了一段从beginIndex到endIndex-1之间的子串

String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);


输出:bc

2. 当substring()被调用时发生了什么?

你可能知道,因为字符串的不可变性,当字符串x赋值为x.substring(1,3)时,它会创造一个新的字符串如下:



然而,上图其实并没有很准确的描述出真正在堆内存中发生的事情。在jdk6和jdk7中,substring()被调用时内存里的改变是不同的

3.jdk6中的substring()

String是用char数组存储的。在jdk6里,String 的类有三个域:char value[],int offset,int count。它们分别用来表示存储真正字符的数组,字符串的头字符在value数组里的位置,字符串的字符长度。

当substring()方法被调用时,它创造了一个新的string字符串,但是这个string字符串的value数组仍然指向内存中原来的数组。不同的是这两个字符串的offset和count不同



接下来的代码简单的解释了这个问题

//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()引起的问题

如果你有一个非常长的string字符串,但是你用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);
}


译者补充

从jdk7开始,string类去除了offset,count两个域。也就是现在的字符串的value数组存储的就是字符串的全部内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: