巫师的蜕变

导航

 

 原文链接: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(int beginIndex,int endIndex)方法的返回值是,从beginIndex开始到endIndex-1结束的字符串.

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

输出结果:

bc

2.执行substring()的时候底层的运行机制是什么?

你可能知道,字符串x是不可变的,当x执行subtring(1,3)方法时候,返回值指向了一个新的字符串。如下图所示:

然而,这个图表并不完全正确。JDK 6和JDK 7在执行substring()究竟发生了什么呢?

3.substring()方法在JDK6中的使用。

字符串后端是char数组形式保存的。在JDK 6中,字符串包含3个字段:char value[],int offset,int count。它们用于存储真正的字符数组、数组的第一个索引、字符串中的字符数。

当substring()方法被调用时,它将创建一个新字符串,字符串的值但仍然指向堆中的同一个数组。两个字符串之间的差值是它们的计数和偏移值。

下面的代码简化了,只包含解释这个问题的关键点:

//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()引发的问题。

如果你有一个很长的字符串,但是你只需要一小部分,每次用substring()。这会导致性能问题,因为你只需要一小部分,你就保留整个事情。JDK 6,解决的办法是使用以下,这将使它指向一个真正的子串:

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

5.substring()方法在JDK7中的使用。

这是在JDK 7的改进。JDK 7中的方法,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);
}

 

posted on 2018-01-12 23:16  jacunjpg  阅读(646)  评论(0编辑  收藏  举报