substring(int beginIndex, int endIndex)方法在JDK6和JDK7是不同的,了解两个版本实现它的不一样能让你更好地运用它们。
java
一、substring()的做用是什么?数组
substring(int beginIndex, int endIndex) 方法返回一个起始位置是beginIndex(包含),结束位置是endIndex-1(包含)的一个字符串。例如:app
Input:性能
String x = "abcdef"; x = x.substring(1,3); System.out.println(x);
Output:ui
bcthis
二、当substring()方法被调用时发生了什么?
spa
你可能知道x是不可变的,当x指向x.substring(1,3)的结果后,它实际上指向一个彻底新的字符串以下:code
然而,这张图并不许确或者它表现的是堆里面真正发生了什么。那当substring()方法被调用时,JDK6和JDK7真正发生了什么不一样呢对象
三、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); }
四、在JDK6的substring()的问题
若是你有很长的字符串,但你每次调用substring()仅仅须要一小部分时,这会引发性能问题。由于你仅仅须要一部分,却要保持整个空间。对于JDK6,下面是一个解决方法,这能让它指向真正的子串:
x = x.substring(x, y) + ""
五、在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));
这样节省了一个对象引用和一点点时间。
我的观点,若有问题,欢迎留言交流~