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

substring(int beginIndex, int endIndex) 方法在 JDK 6 和 JDK 7 中是不同的. 了解他们之间的异同可让你更好地使用这个方法. 为了方便表达,下文中使用 followingsubstring() 代替 substring(int beginIndex, int endIndex) 。 java

1. substring() 都作了什么操做? 数组

substring(int beginIndex, int endIndex) 返回一个 beginIndex 开始到endIndex-1结束字符串 。 app

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

Output: 性能

bc ui

 


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

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

string-immutability

可是上面的图并非彻底的正确描述了substring()方法被调用的时候内存发生了什么变化,它仅仅描述了 堆内存中发生了什么.  code

3. substring() in JDK 6 索引

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

当 substring() 方法被调用的时候, 它会建立一个新的字符串, 但字符串的值仍然指向堆内存中原来的字符串值. 这两个字符串的不一样在于它们的offset count.

string-substring-jdk6

下面的代码简单的演示了发生了什么操做


//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. 在 JDK 6中调用substring()可能会致使一个性能问题

若是你有一个很是长的字符串, 但你每次调用 substring()的时候只截取其中很小的一部分. 由于你只须要很小的一部分,可是在内存中存储了一个很长的数组,这样会致使程序性能很差. 在 JDK 6 中, 咱们将会使用下面的方法来解决这个问题, 它会指向一个新的sub string:

x = x.substring(x, y) + ""

5. substring() in JDK 7

这个方法在JDK 7中有了提高,每一次调用substring()都会在堆内存中建立一个新的字符串数组

string-substring-jdk7


//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));
相关文章
相关标签/搜索