菜鸟译文(三)——JDK6和JDK7中substring()方法的对比

substring(int beginIndex, int endIndex)方法在JDK6和JDK7中是不一样的。了解他们的区别能够让咱们更好的使用这个方法。方便起见,如下用substring() 代替 substring(int beginIndex, int endIndex)。数组

 

1. substring()作了什么?性能

substring(int beginIndex, int endIndex)方法返回一个以beginIndex开头,以endIndex-1结尾的String对象。this

 

String x ="abcdef";

x =x.substring(1,3);

System.out.println(x);

 

输出: spa

bc


 

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

也许你以为,由于x是不可变的,当x通过substring(1,3)处理之后,会指向以下一个全新的String对象: 对象

然而,这张图没有正确的表示出堆内存里真正发生了什么。那么当调用substring()方法时,JDK6和JDK7究竟有什么不一样呢。 blog

 

3. JDK 6中的substring() 内存

String是由一个字符数组实现的,在JDK6中,String类由三部分组成:charvalue[], int offset, int count.。他们才是真正用来存储字符的数组,数组的第一个元素用来存储字符的长度。 字符串

 

当调用substring()方法时,会建立一个新的String对象,可是这个String对象的值仍然指向堆内存中相同的数组。真正不一样的是它们的计数和偏移量。 string

下面的代码已经作了简化,只包含解释这一问题的关键部分。

//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()存在的一个问题

若是有一个很是长的String对象,可是你每次经过substring()只用到其中一小部分。这样就会有一个性能上的问题,对于JDK6来讲,使用如下代码能够解决这个问题,这样作会建立一个真正的子字符串对象:

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


5. JDK 7中的substring()

在JDK7中,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);

}

 

 

原文地址:

http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/

相关文章
相关标签/搜索