String_substring()函数JDK6与JDK7的区别

分享下我的印象笔记~~

1、substring()函数的功能?
     当一个String对象调用substring(int beginIndex,int endIndex)函数时,返回一个以 beginIdex 开始并以 endIndx-1 结束的String对象。String内部表示形式是char[] 。
code:
     @Test
    public void testSubstring(){
         String str = "abcedf";
         System.out.println(str.substring(1,3));
    }
OUTPUT:
     bc
2、当substring函数被调用时,内存中发生的事情?
     正如你所知道的,String对象是不可变的.  当str = str.substring(...)被调用时,内存中会分配一块新的内存地址存放str对象,此时str会指向 ’bc‘。
http://www.programcreek.com/wp-content/uploads/2013/09/string-immutability1-650x303.jpeg
但是这并没有非常精确的表现出内存中真正发生的事情。当substring(...)被调用时,JDK6和JDK7内存中处理是不同的。
3、substring() in JDK6
     String是支持字符数组的,即char[] 。在JDK6中,String类有4个字段,分别是:
           /** The value is used for character storage. */
              private final char value[];

           /** The offset is the first index of the storage that is used. */
             private final int offset;

            /** The count is the number of characters in the String. */
              private final int count;

             /** Cache the hash code for the string */
             private int hash; // Default to 0
    分别被用来 存储一个字符数组,第一个被使用的字符的索引,字符的个数。
     当substring被调用时,创建一个新的String对象,但是字符串值(string's value)依旧指向内存中的同一个字符数组char varry。不同的是 两个String对象的 偏移量offset 和 字符个数 count。
string-substring-jdk6
   'abcedf'对象和 'bc'对象指向的是同一个 char[] 即:[abcedf],也就是说对象 “abced”并不会被GC回收。JDK6中的源代码:

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
    }

return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
    }
4、JDK6引发的问题
     如果有一个 Very long 字符串,但是每次只需要调用substring()函数截取非常小的一部分字符串,这会造成一个性能问题.以后每次只需要 a small part , but keep a whole thing.
     In JDK6 , 有一个解决方案,创建一个新的对象使他指向真实的sub string.
          x = x.string(1,3)+"";
         现在  x 对象中的value 指向了 数组 [b,c];

5、 substring() in JDK7
     这个问题在JDK7中得到了改善,substring() 函数会在内存中真实的创建一个新的char[] 。
string-substring-jdk7
   JDK7 source code :
//JDK 7public 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);

6、Arrays.copyOfRange函数内部
Arrays.copyOfRange函数内部创建了一个新的数组 char[] copy = new char[newLength]; Arrays.copyOfRange 源代码:
public static char[] copyOfRange(char[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
char[] copy = new char[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
 /** The value is used for character storage. */
  private final char value[];

  /** The offset is the first index of the storage that is used. */
  private final int offset;

  /** The count is the number of characters in the String. */
  private final int count;

  /** Cache the hash code for the string */
  private int hash; // Default to 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值