substring()方法在JDK6和JDK7中的区别

substring(int beginIndex, int endIndex) 方法在JDK 7中实现方式是不同于JDK6的,了解这两版本的区别可以帮助你更好的使用它们。简单起见,以下 用substring()代替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);

输出:

bc

2. 当substring被调用时,发生了什么?

你可能知道,字符串x是final不可变的,所以当x被重新赋值为x.substring(1,3)时,它应该指向一个全新的字符串,就像下面图片显示的那样:

string-immutability

但是这张图并不完全正确,它并没有说明内存堆中真正发生了什么。那么substring()方法的到底是怎样工作的呢?在JDK6和JDK7中又有什么区别呢?


3. JDK 6 中的substring()

实际上String类的原理是将字符串存储在一个字符数组中的,在JDK6中,类String包括3个属性域: char value[], int offset, int count,分别用来存储实际的字符数组、数组的第一个索引、字符的个数。

当substring()方法被调用时,一个新的字符串被创建,但是这个字符串的字符数组value仍然指向了原来那个数组的内存堆!惟一不同的是两个字符串的offset和count属性值不同,如下图:

string-substring-jdk6


下面是简化后的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);
}

可以看到value并没有变!


4. JDK6 substring()方法引出的一个问题

如果有一个很长很长的字符串,你每次只需要截取其中很短的一小段,但是如果你用substring()的话实际会得到很长很长的字符串的引用,所以当使用的时候必然导致性能降低! 解决方法可以你下面那样让x指向一个新子串:

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



5. JDK7中的substring()

这个问题在JDK7中被改进了,创建了一个新的字符数组:

string-substring-jdk7

String类在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);
}

可以看到,在构造函数中,创建了一个全新的字符数组value,并且String类中不再使用offset和count做为属性了。


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

原文标题:The substring() Method in JDK 6 and JDK 7


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值