Java subString 方法

jdk7之前substring实现方法

-截取一部分jdk的关键实现

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

jdk7版本之后的实现

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

原因分析

从算法的时间复杂度方面来比较,第一个版本的复杂度为o(1), 第二个版本的复杂度为o(n),但是为什么jdk7之后要选用后面这个实现,只要是因为第一个实现会影响到垃圾回收,第一个版本调用substring不会分配新空间用于存储字符,使用的是原始字符串的字符数组,这样到时原始字符串即使没有了引用了空间也不会被回收,考虑一个特殊场景,当你有一个很长的字符串,但是每次只使用其中一个很小的子串,例如,一下这段程序很出现OOM:

public class TestGC {
    private String largeString = new String(new byte[100000]);
    private String smallString = "foo";

    String getString() {
        // if caller stores this substring, this object will not be gc'ed
        return this.largeString.substring(0,2);
//        return new String(this.largeString.substring(0,2)); // no error here!
//        return smallString; // no error here!
    }

    public static void main(String[] args) {
        java.util.ArrayList list = new java.util.ArrayList();
        for (int i = 0; i < 1000000; i++) {
            TestGC gc = new TestGC();
            list.add(gc.getString());
        }
    }
}

更详细的可以参考http://bugs.java.com/view_bug.do?bug_id=4513622
以及https://stackoverflow.com/questions/16123446/java-7-string-substring-complexity

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值