zoukankan      html  css  js  c++  java
  • JDK6和JDK7中的substring()方法

    substring(int beginIndex, int endIndex)在JDK6与JDK7中的实现方式不一样,理解他们的差异有助于更好的使用它们。为了简单起见,下面所说的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被x.substring(1,3)返回的结果赋值后,它将指向一个全新的字符串如下图:

    这里写图片描述

    然而,这个图并不完全正确,或者说并没有完全表示出java 堆中真正发生的事情。那么当调用substring()的时候到底发生的了什么事呢?JDK 6与JDK7的substring方法实现有什么不一样呢?

    3.JDK6中的substring()

    java中字符串是通过字符数组来支持实现的,在JDK6中,String类包含3个域,char[] value、int offset、int count。分别用于存储真实的字符数组、数组的偏移量,以及String所包含的字符的个数。

    当substring()方法被调用的时候,它会创建一个新的字符串对象,但是这个字符串的值在java 堆中仍然指向的是同一个数组,这两个字符串的不同在于他们的count和offset的值。
    这里写图片描述

    下面是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.jdk6中substring()将会导致的问题

    如果你有一个非常长的字符串,但是你仅仅只需要这个字符串的一小部分,这就会导致性能问题(译注:可能会造成内存泄露,这个bug很早以前就有提及),因为你需要的只是很小的部分,而这个子字符串却要包含整个字符数组,在jdk6中解决办法就是使用下面的方法,它会指向一个真正的子字符串

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

    5.JDK7中的substring()

    在JDK7中有所改进,substring()方法在堆中真正的创建了一个新的数组,当原字符数组没有被引用后就被GC回收了.因此避免了上述问题.
    这里写图片描述

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

    Arrays.copyOfRange(T[ ] original,int from,int to)
    将一个原始的数组original,从下标from开始复制,复制到下标to,生成一个新的数组。

    转载自:http://www.importnew.com/7418.html
    原文https://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/

  • 相关阅读:
    codevs1004 四子连棋
    codevs1009 产生数
    NOIP2014 寻找道路
    Tyvj1139 向远方奔跑(APIO 2009 抢掠计划)
    随机算法
    线性基
    线性基入门
    线性基 + 并查集
    欧拉公式 (平面)
    卡特兰数 + 大数
  • 原文地址:https://www.cnblogs.com/DiZhang/p/12544937.html
Copyright © 2011-2022 走看看