JDK6和JDK7中的substring()方法

         JDK6和JDK7中的substring(int beginIndex, int endIndex)的实现方式是有区别的,知道了这个区别之后可以帮助你更好地在程序中使用substring方法。

         为简单起见,以下使用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被赋予了x.substring(1, 3)时,它指向了一个新的字符串,如下图所示:

但是这个图并不准确或者说这并不能代表在堆中实际发生的事情,该方法的调用在JDK7和JDK6中的实现是完全不同的。

3. JDK6中的substring()

String是通过char数组来实现的。在JDK6中String类包含了3个域:char value[], int offset, int count,分别表示存储的字符数组,该数组的起始索引,以及该字符串中的字符个数。
当方法substring()方法被调用时,它便生成了一个新的字符串,但是该字符串仍旧指向堆中的同一个字符数组,区别就在于偏移量offset和字符个数count的变化,请看下图:

以下简化的代码包含了重要的关键点来解释这个问题:

//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(a, b) + ""

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值