substring()方法在JDK6和JDK7的不同 (翻译外文博客)

substring(int beginIndex, int endIndex)方法在JDK6和JDK7是不一样的,了解两个版本实现它的不同能让你更好地运用它们。

1、substring()的作用是什么?

substring(int beginIndex, int endIndex) 方法返回一个起始位置是beginIndex(包含),结束位置是endIndex-1(包含)的一个字符串。例如:

Input:

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

Output:

bc

2、当substring()方法被调用时发生了什么?

你可能知道x是不可变的,当x指向x.substring(1,3)的结果后,它实际上指向一个完全新的字符串如下:

然而,这张图并不准确或者它表现的是堆里面真正发生了什么。那当substring()方法被调用时,JDK6和JDK7真正发生了什么不同呢

3、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);
}

4、在JDK6的substring()的问题

如果你有很长的字符串,但你每次调用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);
}

(译完,原文链接: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));

这样节省了一个对象引用和一点点时间。

个人观点,如有问题,欢迎留言交流~

时间: 2024-08-01 12:30:46

substring()方法在JDK6和JDK7的不同 (翻译外文博客)的相关文章

菜鸟译文(三)——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对象. Stri

Java中由substring方法引发的内存泄漏

在Java中我们无须关心内存的释放,JVM提供了内存管理机制,有垃圾回收器帮助回收不需要的对象.但实际中一些不当的使用仍然会导致一系列的内存问题,常见的就是内存泄漏和内存溢出 内存溢出(out of memory ):通俗的说就是内存不够用了,比如在一个无限循环中不断创建一个大的对象,很快就会引发内存溢出. 内存泄漏(leak of memory):是指为一个对象分配内存之后,在对象已经不在使用时未及时的释放,导致一直占据内存单元,使实际可用内存减少,就好像内存泄漏了一样. 由substring

在JDK 6和JDK 7的substring()方法的区别?

原文链接:https://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/ 在JDK 6和JDK 7中substring(int beginIndex,int endIndex)的实现是不同的,下面将会做出详细的解释.为简单起见,substring()方法表示的substring(int beginIndex,int endIndex)在这篇文章中的方法. 1.substring()方法 substring

JDK6和JDK7中String类下的substring方法的代码对比(仅贴代码,未详述)

返回主页 回到顶端 jdk1.6版本String.java文件中关于substring的代码及描述 1 /** 2 * Returns a new string that is a substring of this string. The 3 * substring begins with the character at the specified index and 4 * extends to the end of this string. <p> 5 * Examples: 6 *

二 、在 JDK 6 and JDK 7中 substring() 方法

在JDK6 和JDK 7 里面substring(int beginIndex, int endIndex)的方法是不同的.知道这种区别会帮助你更好用它们.为了简单期间,下面用substring() 来表示 substring(int beginIndex,Int endIndex) 方法. 1. substring()方法做什么substring(int beginIndex,int endIndex)方法返回一个从beginIndex开始,到endIndex-1结束的字符串. String

String类的substring方法bug

今天再看JDK源码的时候看到了String类的不同版本的实现方式的不同,主要是substring这个方法,JDK6里面的实现方式是: 很明显可以看到,调用String对象的substring方法后指向的对象地址并没有发生改变,只是改变的是偏移量,这样的话在GC阶段就有可能造成内存泄露了. 还好查了一下资料JDK7解决了这个问题,于是赶紧查看了JDK7的源码: 这个里面是通过内存复制的方式重新指向了一个新的地址,解决了内存泄露的隐患

JS截取字符串substr 和 substring方法的区别

substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 String 对象. start 必选项.所需的子字符串的起始位置.字符串中的第一个字符的索引为 0. length 可选项.在返回的子字符串中应包括的字符个数. 说明 如果 length 为 0 或负数,将返回一个空字符串.如果没有指定该参数,则子字符串将延续到 stringvar 的最后. 示

String中substring方法内存泄漏问题

众所周知,JDK中以前String类中的substring方法存在内存泄漏问题,之所以说是以前,是因为JDK1.7及以后的版本已经修复了,我看都说JDK1.6的版本也存在这个问题,但是我本机上安装的1.6看了看源码不存在内存泄漏问题啊,又看了1.7的源码,和我本机的1.6的一样,是不是我的1.6版版其实是1.7的?!唉,不管了,反正1.7版本肯定没有这个问题(1.5及更老版本肯定有)了,大家就放心的用吧. 之所以存在内存泄漏的问题,是因为原先的版本中,substring是这样实现的: publi

yum change source repo centos共存安装sun jdk6和jdk7

之前一直使用的是163的源,今天从微博看到阿里云推出了自己的源.因为我的主机是阿里云,所以可以走内网,速度提升更快.过程如下:cd /etc/yum.repos.d/mv mv CentOS-Base.repo CentOS-Base.repo.backwget -O CentOS-Base.repo <http://mirrors.aliyuncs.com/repo/Centos-6.repo> yum makecache 因为我是阿里云,可以走内网,系统是6.2如果不是阿里云服务器,则源地