`
lwy520
  • 浏览: 17590 次
  • 性别: 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)了。
感觉是为了解决一个不常出现的问题,把大部分情况下的性能拉低了。

相关推荐

    jdk6_api文档 中文版

    Java的安全模型在JDK6中得到了进一步强化,`java.security`包下的`Policy`、`Permission`和`SecurityManager`类提供了控制程序访问权限的机制。 总结,JDK6 API文档中文版是Java开发者的重要参考资料,它详细阐述了...

    jdk7api帮助文档

    而在JDK7中,实现了自动关闭资源的机制,只要资源实现了`java.lang.AutoCloseable`接口,就可以在try块中直接声明并使用,程序结束时会自动调用`close()`方法。 其次,多线程处理方面,JDK7引入了Fork/Join框架,它...

    jdk7jdk-7u65-windows-x64.rar

    1. **多重异常捕获**:在Java 7中,你可以使用一个"catch"子句来捕获多个不同类型的异常,这样代码更简洁且易于维护。 2. **钻石操作符**:在创建泛型对象时,可以省略类型参数的显式指定,如`new ArrayList()`。...

    jdk6-8String类

    在JDK的不同版本中,`String`类经历了一些优化和改进,尤其是在性能和内存管理方面。这里我们将对JDK 1.6、1.7和1.8中的`String`类进行对比研究,探讨其中的关键变化。 ### JDK 1.6中的String 在JDK 1.6中,`...

    jdk-7u80-windows-x64.exe

    这个版本在当时代表着Java编程语言的最新发展,尽管现在Oracle已经停止了对JDK 7的官方支持,但它仍然是许多开发者和企业中的常用版本,特别是那些仍然依赖于Java 7特性和兼容性的项目。 **Java 7的主要特性:** 1...

    JDK7 Windows64位

    6. **动态类型语言支持**:JDK7开始支持动态类型语言,如Groovy和JRuby,通过Java的invokedynamic指令实现。 7. **并发改进**:`Fork/Join`框架是Java 7引入的一个并行计算框架,可以有效利用多核处理器的计算能力...

    JDK6API中文参考手册[沈东良制]

    以上只是JDK6 API中的一部分关键知识点,实际手册中涵盖了更多细节,包括各种API的使用示例和注意事项,对于Java开发者来说是不可或缺的学习和工作资源。通过深入理解和熟练运用这些API,可以有效地提高编程效率和...

    JDK6API中文参考

    这个中文版的API文档详细介绍了Java Development Kit(JDK)6中的核心类库、接口、方法和异常,帮助开发者理解和利用Java 6平台的功能。以下是基于这个API文档的一些关键知识点: 1. **基础类库**:JDK 6包含了大量...

    jdk1.7.0_17

    在Java 6及更早版本中,你需要明确指定类型参数,如 `new ArrayList()`,但在Java 7中,你可以写成 `new ArrayList()`。 增强的for循环(也称为foreach循环)在Java 7中得到了扩展,可以用于遍历数组和集合,包括...

    JDK1.7 绿色版本免安装,能用希望给个评价,让大家多多支持

    6. **改进的字符串操作** - 包括`switch`语句对字符串的支持,以及`String`类中新增的一些便捷方法,如`substring()`、`trim()`等。 7. **动态类型语言支持** - 通过JSR 292,Java 7引入了对动态语言的支持,允许在...

    Java JDK 6学习笔记——ppt简体版

    作为Java的图形用户界面库,Swing和AWT在JDK 6中提供丰富的组件和布局管理器,用于构建桌面应用。 九、反射 Java反射机制在JDK 6中得以加强,允许程序在运行时动态获取类的信息并调用其方法,增加了程序的灵活性。 ...

    jdk 32位 linux环境

    2. **类型推断**:在Java 7中,引入了`钻石操作符`(`<>`),使得在创建泛型实例时,编译器可以自动推断类型参数,减少了代码的冗余。 3. **字符串切片**:可以通过`substring()`方法的两个参数快速获取子字符串,而...

    JDK1.6中文开发API

    在JDK1.6版本中,Java语言和库经历了许多改进和增强。以下是一些关键知识点: 1. **泛型(Generics)**:JDK1.6全面支持泛型,这使得代码更安全,类型检查在编译时就能完成,避免了运行时的ClassCastException。...

    java学习笔记JDK6课件之六

    在JDK6中,字符串被表示为`String`类的实例,这意味着它具有类的方法和属性,而不是简单的字符数组。 字符串在Java中是不可变的,这意味着一旦创建了一个字符串对象,就不能改变它的内容。例如,当我们执行`text +=...

    JDK6 API文档-沈东良

    1. **泛型的完善**:在JDK 6中,泛型已经成为Java编程的重要组成部分。它允许开发者在编译时检查类型安全,同时减少运行时的类型转换。API文档中,大量的集合框架类和方法都支持了泛型,如ArrayList、HashMap等。 2...

    jdk中文帮助文档

    这份"jdk中文帮助文档"显然是为了方便那些习惯阅读中文或者对英文文档理解有困难的IT从业者准备的,它提供了详细的API参考和指南,使得开发者在使用Java API时能更方便地查找和理解各种类、方法和接口的功能。...

    jdk 9 api帮助文档

    在实际开发中,结合API文档,开发者可以有效地学习和利用JDK 9的新功能,提高代码质量和效率。对于初学者,阅读和查阅API文档是掌握Java编程的重要步骤;对于有经验的开发者,API文档则是解决问题和优化代码的得力...

    jdk-11.0.5_windows-x64_bin

    6. **字符串切片**:Java 11提供了字符串的切片功能,可以通过`.substring()`方法的两个参数来获取子字符串的起始和结束索引。 7. **改进的JShell(REPL)**:Java 11对Java Shell(也称为jshell)进行了增强,使其...

    jdk 1.8 api 带完整目录索引中英文版chm

    7. **反射API:**允许在运行时检查类和接口的结构,创建和访问类的对象,调用方法,访问字段。 8. **注解:**一种元数据,可以添加到代码的多个元素上,用于编译时或运行时进行处理。 9. **异常处理:**try-catch-...

Global site tag (gtag.js) - Google Analytics