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

java的substring()方法在JDK 6和JDK 7中的运作机制

2013-11-29 00:00 459 查看
substring(int beginIndex, int endIndex) 方法在 JDK 6 和 JDK 7 中是不一样的. 了解他们之间的异同可以让你更好地使用这个方法. 为了方便表达,下文中使用 followingsubstring() 代替 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);

Output:

bc



2. 当 substring() 被调用的时候会发生什么?

因为字符串x是不可变的, 当x.substring(1,3)方法返回的字符串赋值给x, 它会像下图那样指向一个全新的字符串:



但是上面的图并不是完全的正确描述了substring()方法被调用的时候内存发生了什么变化,它仅仅描述了 堆内存中发生了什么.

3. substring() in JDK 6

字符串内部是用字符数组来实现的. 在 JDK 6 中, String 包含了3个字段: char value[], int offset, int count. 用它们来存储一个字符数组, 数组在内存中的第一个索引, 字符串包含字符的数量.

当 substring() 方法被调用的时候, 它会创建一个新的字符串, 但字符串的值仍然指向堆内存中原来的字符串值. 这两个字符串的不同在于它们的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. 在 [b]JDK 6中调用substring()可能会导致一个性能问题[/b]

如果你有一个非常长的字符串, 但你每次调用 substring()的时候只截取其中很小的一部分. 因为你只需要很小的一部分,但是在内存中存储了一个很长的数组,这样会导致程序性能不好. 在 JDK 6 中, 我们将会使用下面的方法来解决这个问题, 它会指向一个新的sub string:

x = x.substring(x, y) + ""
5. substring() in JDK 7

这个方法在JDK 7中有了提升,每一次调用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);
}


/**************************我是分隔线******************************/

下面的网友评论中有人提出x = x.substring(x, y) + ""这个方法不好,因为它等同于

StringBuilder sb = new StringBuilder();
sb.append(x.substring(x, y));
sb.append("");
x = sb.toString();


可以用下面的方法来代替x = x.substring(x, y) + ""

x = new String(x.substring(x, y));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息