`
lwy520
  • 浏览: 17047 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

substring在JDK6和JDK7中的区别

 
阅读更多

 

这是本人第一次翻译及时文档,如有差池,还请多多体谅,本人还是觉得,如果读者英文功底,还可以的话,建议看原文:http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/    

 

为简单起见,列举如下例子来说明substring(int beginIndex,int endIndex)方法。

1,substring()方法具体是做什么的?

       substring(int beginIndex , int  endIndex)方法返回一个从beginIdex开始到endIndex-1的新串。

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

 输出结果:

 

               bc

2,substring()方法什么时候被调用?

       我们知道对于String的长度是不变的,当x调用substring(1,3)方法后,返回的结果会指向一个全新的字符串,如下:

string-immutability

     然而,上图并不完全正确反应出substring()方法在堆中发生的情况,在JDK 6 和JDK 7中是有区别的。

 

3,JDK 6中的substring()方法

     由于字符串支持字符数组,在JDK 6 中,有这样一个构造器。

String
public String(char[] value,
              int offset,
              int count)分配一个新的 String,它包含取自字符数组参数一个子数组的字符。offset 参数是子数组第一个字符的索引,count 参数指定子数组的长度。该子数组的内容已被复制;后续对字符数组的修改不会影响新创建的字符串。 

参数:
value - 作为字符源的数组。
offset - 初始偏移量。
count - 长度。 

 

      当substring()方法被调用后,会创建一个新的字符串,但是这个新的字符串仍旧指向原来字符串在堆中的地址,这两个字符串的区别就是他们的长度和初始偏移量。

string-substring-jdk6

 

如下的一段伪代码用来解释这个问题:

//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,JDK 7 中的substring()方法

     JDK 7改进了substring()方法,在其被调用后会在堆中新开辟内存空间。

string-substring-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);

 

 

3
4
分享到:
评论
2 楼 yangkyy 2013-09-25  
new String(offset + beginIndex, endIndex - beginIndex, value);
在JDK1.6中的代码如下:
this.value = Arrays.copyOfRange(value, offset, offset+count);
也就是对原数组进行了复制,内存地址怎么还会一样呢,求解释
1 楼 mike.liu 2013-09-25  
在一次优化性能的时候,惊讶于substring()的性能,出奇的高。就是因为它不需要new新的字符数组内存并拷贝子串。如JDK7真这样改了,此函数的性能肯定大打折扣。未必是一种优化。

如果如楼主所述,JDK6中的substring()算法复杂度是0(1)的,而JDK7中,则变为O(n)了。
感觉是为了解决一个不常出现的问题,把大部分情况下的性能拉低了。

相关推荐

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

    主要介绍了Java中由substring方法引发的内存泄漏详解,涉及substring方法引发的内存泄漏简介,substring的作用和实现原理等相关内容,具有一定借鉴价值,需要的朋友可以参考下

    了解String.substring的原理

    首先我们要了解String对象放入常量池的时机验证2.substring返回时究竟发生了什么操作JDK1.6中的substringJDK1.6中的substring中产生的问题JDK1.7中的substring 1.首先我们要了解String对象放入常量池的时机 String只...

    新版Java为什么要修改substring的实现

    有意思的是,这个方法从jdk1.0开始,一直到1.6都没有变化,但到了1.7实现方式却发生了改变。你可能会认为之所以要对一个成熟且稳定的方法做修改,一定是因为新的实现更好、效率更高吧?然而正好相反,修改后的...

    JavaFocus::hammer: Java重点内容 博客文章 样例

    JavaFocus:hammer: Java学习重点 ...success和isSuccessequals 和 ==String为什么是不可变的字符串常量池为什么直接定义的字符串可以调用String对象的各种方法JDK6 和 JDK7 substring原理的改变字符串拼接的几种方式

    Java初学者如何自学和自己定位解决问题

    OneCoder其实没有资格高谈阔论,只能说说个人的习惯和方式。自学和自我解决问题确实是一项非常非常重要的能力,远比你现在所会的知识重要的多的多,因为,你未知的...  比如,你用到了String类中的subString方法,想知

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中的运用 42 2.3 名称空间和dtd 43 2.4 小结 45 第3章 对xml文档进行分析 46 3.1 dom、...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中的运用 42 2.3 名称空间和dtd 43 2.4 小结 45 第3章 对xml文档进行分析 46 3.1 dom、...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中的运用 42 2.3 名称空间和dtd 43 2.4 小结 45 第3章 对xml文档进行分析 46 3.1 dom、...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中的运用 42 2.3 名称空间和dtd 43 2.4 小结 45 第3章 对xml文档进行分析 46 3.1 dom、...

    Java范例开发大全 (源程序)

     1.2.4 测试JDK配置是否成功 7  实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制...

    java范例开发大全(pdf&源码)

    1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 ...

    java范例开发大全源代码

     1.2.4 测试JDK配置是否成功 7  实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之...

    java范例开发大全

    1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 ...

    Java 免费给手机发飞信

    必须使用jdk 1.6 二 Exception in thread "main" java.lang.RuntimeException: Your license has expired. Please registe ...,Your key is @2AC*1A97~C@6DCF6B8FEFE03@6B4C&CCAFF92 需要key的 可以去这弄...

    Java范例开发大全(全书源程序)

    1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...

    springmybatis

    3. 在session 中完成对数据的增删改查和事务提交等. 4. 在用完之后关闭session 。 5. 在java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。 mybatis实战教程(mybatis in action)之一:开发环境搭建 ...

Global site tag (gtag.js) - Google Analytics