查看原文
其他

注意:字符串substring方法在jkd6,7,8中的差异。

2017-11-29 javastack Java技术栈

QQ用得起来越少了,现在就加入300+技术微信群,公众号回复"微信群"即可加入。

标题中的substring方法指的是字符串的substring(int beginIndex, int endIndex)方法,这个方法在jdk6,7是有差异的。

substring有什么用?

substring返回的是字符串索引位置beginIndex开始,endIndex-1结束的字符串。

来看这个例子:

  1. String x = "abcdef";

  2. x = x.substring(1,3);

  3. System.out.println(x);

输出:

  1. bc

下面看看在JDK之间,它们的实现原理有什么不一样,及值得注意的地方。

JDK 6

String背后是由char数组构成的,在JDK6中,String包含三个字段:char value[], int offset, int count,意思很简单。

substring被调用时,它会创建一个新的字符串,但字符串的值还指向堆中同样的字符数组。它们的区别只是数量和下标引用不一样,如图所示。

JDK6中的部分源码可以说明这个问题。

  1. //JDK 6

  2. String(int offset, int count, char value[]) {

  3.    this.value = value;

  4.    this.offset = offset;

  5.    this.count = count;

  6. }

  7. public String substring(int beginIndex, int endIndex) {

  8.    //check boundary

  9.    return  new String(offset + beginIndex, endIndex - beginIndex, value);

  10. }

会有什么问题?

如果一个很长的字符串,但是每次使用substring(),你只需要很小的一部分。这将会导致性能问题,因为只需要一小部分,却引用了整个字符数组内容。对于JDK 6,解决方案是使用以下内容:

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

JDK 7,8

JDK6这种问题在JDK7+中已经改善了,JDK7+中实际是重新创建了一个字符数组,如图。

JDK7中的部分源码,JDK8类似。

  1. //JDK 7

  2. public String(char value[], int offset, int count) {

  3.    //check boundary

  4.    this.value = Arrays.copyOfRange(value, offset, offset + count);

  5. }

  6. public String substring(int beginIndex, int endIndex) {

  7.    //check boundary

  8.    int subLen = endIndex - beginIndex;

  9.    return new String(value, beginIndex, subLen);

  10. }

对于JDK的这种差异,我们知道就好,现在应该都是JDK7及8了吧,其实对于小字符串的这种操作性能也是可以忽略不计的。

推荐阅读



阿里高级Java面试题(首发,70道,带详细答案)

2017派卧底去阿里、京东、美团、滴滴带回来的面试题及答案

Spring面试题(70道,史上最全)

17张图揭密支付宝系统架构

阿里巴巴,排行前10的开源项目!

2018年必看:关于区块链技术的10本书



  Java技术栈  
微信公众号:「Javastack

分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。
 ▼长按二维码关注我们↓↓↓



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存